zoj3732(度序列判断是否可图且是否唯一)
2016-09-23 11:44
281 查看
Graph Reconstruction
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 410 Accepted Submission(s): 1
[align=left]Problem Description[/align]
Let there be a simple graph with N vertices but we just know the degree of each vertex. Is it possible to reconstruct the graph only by these information?
A simple graph is an undirected graph that has no loops (edges connected at both ends to the same vertex) and no more than one edge between any two different vertices. The degree of a vertex is the number of edges that connect to it.
[align=left]Input[/align]
There are multiple cases. Each case contains two lines. The first line contains one integer N (2 ≤ N ≤ 100), the number of vertices in the graph. The second line contains N integers in which the ith item is the degree of
ith vertex and each degree is between 0 and N-l(inclusive).
[align=left]Output[/align]
If the graph can be uniquely determined by the vertex degree information, output "UNIQUE" in the first line. Then output the graph.
If there are two or more different graphs can induce the same degree for all vertices, output "MULTIPLE" in the first line. Then output two different graphs in the following lines to proof.
If the vertex degree sequence cannot deduce any graph, just output "IMPOSSIBLE". The output format of graph is as follows:
N E
u1 u2 ... uE
v1 v2 ... vE
Where N is the number of vertices and E is the number of edges, and {ui,vi} is the ith edge of the graph. The order of edges and the order of vertices in the edge representation is not important since we would use special judge to verify your answer.
The number of each vertex is labeled from 1 to N. See sample output for more detail.
[align=left]Sample Input[/align]
1
0
6
5 5 5 4 4 3
6
5 4 4 4 4 3
6
3 4 3 1 2 0
[align=left]Sample Output[/align]
UNIQUE
1 0
UNIQUE
6 13
3 3 3 3 3 2 2 2 2 1 1 1 5
2 1 5 4 6 1 5 4 6 5 4 6 4
MULTIPLE
6 12
1 1 1 1 1 5 5 5 6 6 2 2
5 4 3 2 6 4 3 2 4 3 4 3
6 12
1 1 1 1 1 5 5 5 6 6 3 3
5 4 3 2 6 4 3 2 4 3 4 2
IMPOSSIBLE
声明:此题在杭电千万别提交!杭电discuss里说这题不是spj……!!!!
题意:给出一个度序列,让你判断能否构建原图且判断原图是否唯一。
思路:构建原图好判断,关键在判断是否唯一,我的想法判断两条边能否交换位置,网上的思路是进行贪心建图的时候判断是否最后一个点p点与p+1点的度数相等,如果相等则至少存在两种建图方式。气人的是hdu未能使用spj!!怎么交怎么wa……
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include<string.h>
#include<vector>
#include<queue>
#include<algorithm>
#include<stdio.h>
#include<math.h>
#include<map>
#include<stdlib.h>
#include<time.h>
#include<stack>
#include<set>
using namespace std;
typedef long long ll;
struct data
{
int du,id;
} a[110],b[110];
bool cmp(data a,data b)
{
return a.du>b.du;
}
int ans1[10000000],ans2[10000000];
int tu[1100][1100];
int bj,one;
/*bool Havel_Hakimi(int n,data *arr)
{
for(int i=0; i<n-1; ++i)
{
sort(arr+i,arr+n,cmp);
if(i+arr[i].du>= n) return false;
for(int j=i+1; j<=i+arr[i].du ; j++)
{
--arr[j].du;
if(arr[j].du < 0) return false;
ans1[bj]=arr[i].id;
ans2[bj++]=arr[j].id;
tu[arr[i].id][arr[j].id]=tu[arr[j].id][arr[i].id]=1;
}
}
if(arr[n-1].du!=0)return false;
return true;
}*/
bool judge(int n)
{
sort(a,a+n,cmp);
one=1;
for(int k = 0; k <n; ++k)
{
sort(a+k,a+n,cmp);
if(a[k].du > n - k)
return false;
if(!a[k].du)break;
if(one&&(k+a[k].du+1<n)&&(a[k+a[k].du].du==a[k+a[k].du+1].du))
one=0;
for(int j = 1; j <= a[k].du; ++j)
{
if(--a[k+j].du < 0) return false;
tu[a[k].id][a[k+j].id] = tu[a[k+j].id][a[k].id]=1;
ans1[bj]=a[k].id;
ans2[bj++]=a[k+j].id;
}
}
return true;
}
bool judge2(int n)
{
int ff=0;
sort(b,b+n,cmp);
for(int k = 0; k <n; ++k)
{
sort(b+k,b+n,cmp);
if(b[k].du > n - k)
return false;
if(!b[k].du)break;
if(!ff&&(k+b[k].du+1<n)&&(b[k+b[k].du].du==b[k+b[k].du+1].du))
{
//cout<<b[k+b[k].du].id<<" "<<b[k+b[k].du+1].id<<endl;
int id=b[k+b[k].du].id;
b[k+b[k].du].id=b[k+b[k].du+1].id;
b[k+b[k].du+1].id=id;
ff=1;
}
for(int j = 1; j <= b[k].du; ++j)
{
if(--b[k+j].du < 0) return false;
ans1[bj]=b[k].id;
ans2[bj++]=b[k+j].id;
}
}
return true;
}
/*int Havel(int n)
{
int i,j;
for(i=0; i<n; i++)
{
sort(a+i,a+n,cmp);//每次都要排序
j=a[i].id;//记录头的坐标
int v=a[i].du;
if(v>n-i-1)//如果该点的度超过剩下的数 则不存在图
{
return 0;
}
for(int k=1; k<=v; k++) //开始减度
{
int x=a[k+i].id;
a[k+i].du--;
if(a[k+i].du<0)return 0;//为负数时2无图
tu[j][x]=tu[x][j]=1;
ans1[bj]=j;
ans2[bj++]=x;
}
}
return 1;
}
*/
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(tu,0,sizeof(tu));
int sum=0;
for(int i=0; i<n; i++)
{
scanf("%d",&a[i].du);
b[i].du=a[i].du;
b[i].id=a[i].id=i+1;
sum+=a[i].du;
}
if(sum&1)
puts("IMPOSSIBLE");
else
{
bj=0;
bool flag=judge(n);
if(!flag)
puts("IMPOSSIBLE");
else
{
if(one)
{
puts("UNIQUE");
printf("%d %d\n",n,sum/2);
for(int i=0; i<bj; i++)
if(i==0)
printf("%d",ans1[i]);
else printf(" %d",ans1[i]);
puts("");
for(int i=0; i<bj; i++)
if(i==0)
printf("%d",ans2[i]);
else
printf(" %d",ans2[i]);
puts("");
}
else
{
puts("MULTIPLE");
printf("%d %d\n",n,sum/2);
for(int i=0; i<bj; i++)
if(i==0)
printf("%d",ans1[i]);
else printf(" %d",ans1[i]);
puts("");
for(int i=0; i<bj; i++)
if(i==0)
printf("%d",ans2[i]);
else
printf(" %d",ans2[i]);
puts("");
bj=0;
judge2(n);
printf("%d %d\n",n,sum/2);
for(int i=0; i<bj; i++)
if(i==0)
printf("%d",ans1[i]);
else printf(" %d",ans1[i]);
puts("");
for(int i=0; i<bj; i++)
if(i==0)
printf("%d",ans2[i]);
else
printf(" %d",ans2[i]);
puts("");
}
}
}
}
return 0;
}
相关文章推荐
- POJ 1094 Sorting It All Out (拓扑排序,判断序列是否唯一,图是否有环)
- topo排序(邻接表) 判断topo序列是否存在,是否唯一,以及输出序列
- 判断一个字符串是否能够通过添加一个字符变成回文序列的方法
- HDU 1022 Train Problem I(判断出栈序列是否可行)
- poj 1679 The Unique MST (判断最小生成树是否唯一)
- 判断MST是否唯一
- poj 1868 Antiarithmetic? 判断序列中是否有等差子序列
- 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一
- python简单判断序列是否为空的方法
- 程序员面试题100题第24题——判断是否是push、pop序列
- Solution 9: 判断序列是否为BST的后续遍历结果
- Train Problem——判断输出序列是否是输入序列的出栈顺序
- 判断一个数是否能分解为某个连续正整数序列之和
- Miscellaneous | 不适用额外空间判断字符是否唯一
- poj 1679 判断最小生成树是否唯一
- OJ2140图结构练习——判断给定图是否存在合法拓扑序列
- 判断一个序列是否是另外一个序列的子序列的算法
- 判断一个序列是否是一个二叉查找树的后序遍历结果
- 笔试面试之判断序列是否2叉查找树后序遍历
- [poj 1659 ]Frogs\' Neighborhood(Havel-Hakimi定理(判断一个序列是否可图))