0
点赞
收藏
分享

微信扫一扫

HDU 1811 Rank of Tetris(拓扑排序确定排名,排名有重复的情况)


题目地址:​​点击打开链接​​

思路:

拓扑排序的两个性质:


①如果一次入队入度为零的点大于1则说明拓扑排序序列不唯一


②如果排序的总个数小于给定的个数,则说明存在回路


用并查集把成绩相等的人放在一起。
然后根据关系,把他们连起来。
然后拓扑排序。
如果拓扑排序结束之后,拓扑到的边数和输入的边数不同,那么肯定出现环了,那么就是信息错误。0
否则,如果某个时刻出现两个点的入度都为0,那么就出现信息不完整。
其他的就是结果正确了。



最后判断我写的是sum!=0不行,没搞懂原因



AC代码:



#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>

using namespace std;

const int maxn = 10010;

struct H
{
int left,right;
char op;
}xp[20010];

struct node
{
int v,next;
}lol[20010];

int pre[maxn],head[maxn],in[maxn],edgenum;

int find(int x)
{
return x == pre[x] ? x : pre[x] = find(pre[x]);
}

void merge(int x,int y)
{
int a,b;
a = find(x);
b = find(y);
if(a != b)
{
//pre[x] = y;这都写错。。。
pre[a] = b;
}
}

void add(int x,int y)
{
lol[edgenum].v = y;
lol[edgenum].next = head[x];
head[x] = edgenum++;
}

int main()
{
int n,m,i;
while(scanf("%d%d",&n,&m) != EOF)
{
edgenum = 0;
for(i=0; i<n; i++)
{
pre[i] = i;
head[i] = -1;
in[i] = 0;
}
int sum = n;
for(i=0; i<m; i++)
{
scanf("%d %c %d",&xp[i].left,&xp[i].op,&xp[i].right);
if(xp[i].op == '=')
{
merge(xp[i].left,xp[i].right);
sum--;
}
}
edgenum = 0;
int a,b;
for(i=0; i<m; i++)
{
if(xp[i].op == '=')
continue;
a = find(xp[i].left);
b = find(xp[i].right);
if(a == b)
{
break;
}
if(xp[i].op == '<')
{
add(b,a);
in[a]++;
}
else
{
add(a,b);
in[b]++;
}
}
if(i != m)
{
printf("CONFLICT\n");
continue;
}
queue<int> que;
for(i=0; i<n; i++)
{
if(!in[i] && i == pre[i])
que.push(i);
}
int k;
int flag = 0;
while(!que.empty())
{
k = que.front();
que.pop();
sum--;
if(!que.empty())
{
flag = 1;
//break;不能退出,不然不能判断是因为缺信息还是信息不完全的原因
}
for(i=head[k]; i != -1; i = lol[i].next)
{
in[lol[i].v]--;
if(!in[lol[i].v])
que.push(lol[i].v);
}
}
if(sum > 1)//这里不能用sum != 0,
{
printf("CONFLICT\n");
continue;
}
if(flag)
printf("UNCERTAIN\n");
else
printf("OK\n");
}
return 0;
}

AC代码:



#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>

using namespace std;

const int maxn = 10010;

struct H
{
int left,right;
char op;
}xp[20010];

struct node
{
int v,next;
}lol[20010];

int pre[maxn],head[maxn],in[maxn],edgenum;

int find(int x)
{
return x == pre[x] ? x : pre[x] = find(pre[x]);
}

void merge(int x,int y)
{
int a,b;
a = find(x);
b = find(y);
if(a != b)
{
//pre[x] = y;这都写错。。。
pre[a] = b;
}
}

void add(int x,int y)
{
lol[edgenum].v = y;
lol[edgenum].next = head[x];
head[x] = edgenum++;
}

int main()
{
int n,m,i;
while(scanf("%d%d",&n,&m) != EOF)
{
edgenum = 0;
for(i=0; i<n; i++)
{
pre[i] = i;
head[i] = -1;
in[i] = 0;
}
int sum = n;
for(i=0; i<m; i++)
{
scanf("%d %c %d",&xp[i].left,&xp[i].op,&xp[i].right);
if(xp[i].op == '=')
{
merge(xp[i].left,xp[i].right);
sum--;
}
}
edgenum = 0;
int a,b;
for(i=0; i<m; i++)
{
if(xp[i].op == '=')
continue;
a = find(xp[i].left);
b = find(xp[i].right);
if(a == b)
{
break;
}
if(xp[i].op == '<')
{
add(b,a);
in[a]++;
}
else
{
add(a,b);
in[b]++;
}
}
if(i != m)
{
printf("CONFLICT\n");
continue;
}
queue<int> que;
for(i=0; i<n; i++)
{
if(!in[i] && i == pre[i])
que.push(i);
}
int k;
int flag = 0;
while(!que.empty())
{
k = que.front();
que.pop();
sum--;
if(!que.empty())
{
flag = 1;
//break;不能退出,不然不能判断是因为缺信息还是信息不完全的原因
}
for(i=head[k]; i != -1; i = lol[i].next)
{
in[lol[i].v]--;
if(!in[lol[i].v])
que.push(lol[i].v);
}
}
if(sum > 0)
{
printf("CONFLICT\n");
continue;
}
if(flag)
printf("UNCERTAIN\n");
else
printf("OK\n");
}
return 0;
}



#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>

using namespace std;

const int maxn = 10010;

struct H
{
int left,right;
char op;
}xp[20010];

struct node
{
int v,next;
}lol[20010];

int pre[maxn],head[maxn],in[maxn],edgenum;

int find(int x)
{
return x == pre[x] ? x : pre[x] = find(pre[x]);
}

void merge(int x,int y)
{
int a,b;
a = find(x);
b = find(y);
if(a != b)
{
//pre[x] = y;这都写错。。。
pre[a] = b;
}
}

void add(int x,int y)
{
lol[edgenum].v = y;
lol[edgenum].next = head[x];
head[x] = edgenum++;
}

int main()
{
int n,m,i;
while(scanf("%d%d",&n,&m) != EOF)
{
edgenum = 0;
for(i=0; i<n; i++)
{
pre[i] = i;
head[i] = -1;
in[i] = 0;
}
int sum = n;
for(i=0; i<m; i++)
{
scanf("%d %c %d",&xp[i].left,&xp[i].op,&xp[i].right);
if(xp[i].op == '=')
{
merge(xp[i].left,xp[i].right);
sum--;
}
}
edgenum = 0;
int a,b;
for(i=0; i<m; i++)
{
if(xp[i].op == '=')
continue;
a = find(xp[i].left);
b = find(xp[i].right);
if(a == b)
{
break;
}
if(xp[i].op == '<')
{
add(b,a);
in[a]++;
}
else
{
add(a,b);
in[b]++;
}
}
if(i != m)
{
printf("CONFLICT\n");
continue;
}
queue<int> que;
for(i=0; i<n; i++)
{
if(!in[i] && i == pre[i])
que.push(i);
}
int k;
int flag = 0;
while(!que.empty())
{
k = que.front();
que.pop();
sum--;
if(!que.empty())
{
flag = 1;
//break;不能退出,不然不能判断是因为缺信息还是信息不完全的原因
}
for(i=head[k]; i != -1; i = lol[i].next)
{
in[lol[i].v]--;
if(!in[lol[i].v])
que.push(lol[i].v);
}
}
printf("%d\n",sum);
if(sum > 0)//这里不能用sum != 0,别人>1也能过
{
printf("CONFLICT\n");
continue;
}
if(flag)
printf("UNCERTAIN\n");
else
printf("OK\n");
}
return 0;
}




举报

相关推荐

0 条评论