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

思路

引用题解:

将顶点按能到达的点数从小到大排序,排好序之后每个点只能往前面的点连边. 因而如果存在一个排在第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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值