zoukankan      html  css  js  c++  java
  • 2013亚洲区域赛长沙站 ZOJ 3732 Graph Reconstruction

    题目链接

    Graph Reconstruction

    题意

    给你无向图每个点的度数, 问是否存在唯一解, 存在输出唯一解, 多解输出两个, 无解输出IMPOSSIBLE

    思路

    这里用到了 Havel-Hakimi定理, 实际上就是按照度数构图的一种贪心策略. 这样能判断出来一个解或无解, 多解的情况, 只要在比较构图时最后面两个点的当前度数一样, 那么选其一都是可行的, 但是选其一的情况有保证了另外一个肯定没有连上, 所以能找到其它解.

    代码

    #include <bits/stdc++.h>
    
    #define LL long long
    #define INF 0x3f3f3f3f
    #define eps 1e-8
    
    using namespace std;
    
    struct Node{
    	int val, pos;
    }d[105], b[105];
    pair<int, int> res1[10005], res2[10005];
    int cnt1, cnt2;
    bool compare(Node x, Node y){
    	return x.val > y.val;
    }
    
    int main(){
    #ifndef ONLINE_JUDGE
    	freopen("in.txt", "r", stdin);
    	//freopen("out.txt", "w", stdout);
    #endif // ONLINE_JUDGE
    	int n;
    	while (~scanf("%d", &n)){
    		bool noans = false;
    		cnt1 = cnt2 = 0;
    		for (int i = 1; i <= n; i++){
    			scanf("%d", &d[i].val);
    			d[i].pos = i;
    			if (d[i].val > n - 1) noans = true;
    			b[i] = d[i];
    		}
    		sort(d + 1, d + n + 1, compare);
    		bool isunique = true;
    		while (!noans){
    			if (d[1].val == 0) break;
    			for (int i = 2; i < 2 + d[1].val; i++){
    				d[i].val--;
    				res1[cnt1++] = make_pair(d[1].pos, d[i].pos);
    				if (d[i].val < 0){
    					noans = true;
    					break;
    				}
    			}
    			if (d[2 + d[1].val].val - d[1 + d[1].val].val == 1){
    				isunique = false;
    			}
    			d[1].val = 0;
    			sort(d + 1, d + n + 1, compare);
    		}
    		if (noans){
    			printf("IMPOSSIBLE
    ");
    			continue;
    		}
    		if (isunique){
    			printf("UNIQUE
    ");
    		}
    		else{
    			printf("MULTIPLE
    ");
    			for (int i = 1; i <= n; i++){
    				d[i] = b[i];
    			}
    			sort(d + 1, d + n + 1, compare);
    			bool first = true;
    			while (d[1].val != 0){
    				for (int i = 2; i < 1 + d[1].val; i++){
    					d[i].val--;
    					res2[cnt2++] = make_pair(d[1].pos, d[i].pos);
    				}
    				if (first && d[1 + d[1].val].val == d[2 + d[1].val].val){
    					first = false;
    					d[2 + d[1].val].val--;
    					res2[cnt2++] = make_pair(d[1].pos, d[2 + d[1].val].pos);
    				}
    				else{
    					d[1 + d[1].val].val--;
    					res2[cnt2++] = make_pair(d[1].pos, d[1 + d[1].val].pos);
    				}
    				d[1].val = 0;
    				sort(d + 1, d + n + 1, compare);
    			}
    		}
    		printf("%d %d
    ", n, cnt1);
    		for (int i = 0; i < cnt1; i++){
    			printf("%d ", res1[i].first);
    		}
    		printf("
    ");
    		for (int i = 0; i < cnt1; i++){
    			printf("%d ", res1[i].second);
    		}
    		printf("
    ");
    		if (!isunique){
    			printf("%d %d
    ", n, cnt2);
    			for (int i = 0; i < cnt2; i++){
    				printf("%d ", res2[i].first);
    			}
    			printf("
    ");
    			for (int i = 0; i < cnt2; i++){
    				printf("%d ", res2[i].second);
    			}
    			printf("
    ");
    		}
    	}
    }
    
  • 相关阅读:
    据说,能找出15个以上的的视力才正常....
    看看用PS来转基因的动物,居然很欢乐!!
    《天引》读书笔记——由新月形面积引发的人类长达2000年的探索。
    练习使用策略模式
    折半查找
    UltraEdit常用配置&搭建Java/C开发环境
    一个操作系统的实现_十分钟完成的操作系统——到这里博客迁移工作圆满结束
    C++中的变量初始化
    LeetCode Range Sum Query
    Peeking Iterator
  • 原文地址:https://www.cnblogs.com/macinchang/p/4927308.html
Copyright © 2011-2022 走看看