题意:对N个人进行排名,给定两个人A、B,A>B A=B A<B。如果能得到唯一确定的排名输出OK,如果信息不完全输出UNCERTAIN如果有冲突输出CONFLICT
做法:将等于关系的放入一个集合中,对每个集合的根进行拓扑排序,发现有多种排序结果为UNCERTAIN 有环为CONFLICT
#include<stdio.h>
#include<string.h>
#include<queue>
#include<vector>
#include<iostream>
using namespace std;
const int maxn=10005;
const int maxm=20005;
intn,m,f[maxn],x[maxm],y[maxm],son[maxn];
char ope[maxm];
vector<int> g[maxn];
void initSet(int n)
{
for(inti=0;i<=n;i++)f[i]=i;
for(inti=0;i<=n;i++)g[i].clear();
memset(son,0,sizeof(son));
}
int find(int x)
{
returnx==f[x]?f[x]:f[x]=find(f[x]);
}
bool Union(int x,int y)
{
inta=find(x),b=find(y);
if(a==b)return false;
if(a>b)f[b]=a;
else
{
f[a]=b;
}
return true;
}
int main()
{
while(scanf("%d %d",&n,&m)!=EOF)
{
initSet(n);
int num=n;
for(inti=0;i<m;i++)
{
scanf("%d %c %d",&x[i],&ope[i],&y[i]);
if(ope[i]=='=')
{
if(Union(x[i],y[i]))num--;
}
}
for(inti=0;i<m;i++)
{
if(ope[i]!='=')
{
intxx=find(x[i]),yy=find(y[i]);
if(ope[i]=='>')
{
g[xx].push_back(yy);
son[yy]++;
}
else
{
g[yy].push_back(xx);
son[xx]++;
}
}
}
queue<int> q;
for(inti=0;i<n;i++)
{
if(son[i]==0&&i==find(i))q.push(i);
}
int stan=0;
while(!q.empty())
{
if(q.size()>1)stan=1;
int t=q.front();
q.pop();
--num;
for(int v=0;v<g[t].size();++v)
{
if(--son[g[t][v]]==0)q.push(g[t][v]);
}
}
// cout<<"?????????"<<endl;
if(num>0)cout<<"CONFLICT"<<endl;
else if(stan==1)cout<<"UNCERTAIN"<<endl;
else cout<<"OK"<<endl;
}
return 0;
}
本文介绍了一种使用拓扑排序与并查集解决排名问题的方法。通过将相等关系的人群归并,并对每个集合的根节点进行拓扑排序来判断是否能得出唯一的排名顺序。如果出现多种排序可能性则输出不确定,若存在冲突则输出冲突。
&spm=1001.2101.3001.5002&articleId=52127568&d=1&t=3&u=2c6953cae10848529040fbb922a64047)
263

被折叠的 条评论
为什么被折叠?



