您的位置:首页 > 大数据 > 人工智能

(HDU 5813)2016 Multi-University Training Contest 7 Elegant Construction (贪心、图论)

2016-08-09 22:34 399 查看

思路

引用题解:

将顶点按能到达的点数从小到大排序,排好序之后每个点只能往前面的点连边. 因而如果存在一个排在第i位的点,要求到达的点数大于i-1,则不可行;否则就可以按照上述方法构造出图. 复杂度O(N^2).

之所以要排序,是为了保证每加一条边时,只增加一个点,而不是多个(最喜欢spj了。。)

代码

#include <bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=a;i<b;i++)
#define debug(a) printf("a =: %d\n",a);
const int INF=0x3f3f3f3f;
const int maxn=1e3+50;
const int Mod=1000000007;
const double PI=acos(-1);
typedef long long ll;
using namespace std;

int n;

struct Node{
int id,x;
bool operator<(const Node &r)const{
return x<r.x;
}
};
Node s[maxn];

struct Edge{
int u,v;
Edge(){}
Edge(int a,int b){
u=a; v=b;
}
};
void display(vector<Edge> &v){
int sz=v.size();
printf("%d\n", sz);
for(int i=0;i<sz;i++){
printf("%d %d\n", v[i].u,v[i].v);
}
}
bool solve(vector<Edge> &v){
for(int i=1;i<=n;i++){
int tar=s[i].x;
if (tar>=i) return false;
for(int j=1;j<=tar;j++){
v.push_back(Edge(s[i].id,s[j].id));
}
}
return true;
}

int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif

int T; scanf("%d",&T);
for(int cs=1;cs<=T;cs++){
scanf("%d",&n);
for(int i=1;i<=n;i++) {
s[i].id=i;
scanf("%d",&s[i].x);
}
sort(s+1,s+n+1);
vector<Edge> v;
if (solve(v)){
printf("Case #%d: Yes\n",cs);
display(v);
}else printf("Case #%d: No\n",cs);

}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐