您的位置:首页 > 其它

HDU 1811 Rank of Tetris

2016-07-23 19:40 423 查看
题意:

给出n个人(编号为0~n-1)m种信息,分为三种情况"A > B","A = B","A < B",分别表示A的Rating高于B,等于B,小于B,若Rating值一样编号大的排前面。问你是否能完成1~n-1的排名。

思路:

把所有相等的当成一个人来看,因为相等的内部肯定可以按编号大小来排。然后进行拓扑排序,只存在一个入度为0的点且能完成拓扑的才输出OK。其他的若不能完成拓扑输出CONFLICT(包括有多个入度为0),若能完成拓扑,但有多个入度为0的输出UNCERTAIN。

#include<cstdio>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;

const int MAXN=10005;
const int MAXM=20005;
int n,m,fa[MAXN],u[MAXM],v[MAXM],in[MAXN];
char op[MAXM][5];
bool vis[MAXN];
vector<int> gr[MAXN];

void init(){
for(int i=0;i<n;i++){
fa[i]=i;
in[i]=0;
gr[i].clear();
}
}

int Find(int x){
int r=x,t;
while(r!=fa[r]){
r=fa[r];
}
while(x!=r){
t=fa[x];
fa[x]=r;
x=t;
}
return r;
}

void Union(int u,int v){
int a=Find(u);
int b=Find(v);
if(a!=b){
fa[a]=b;
}
}

int Tuopu(){
queue<int> Q;
int num=0;
bool flag1=true,flag2=true;
memset(vis,false,sizeof(vis));
for(int i=0;i<n;i++){
int u=Find(i);
if(in[u]==0&&vis[u]==false){
Q.push(u);
num++;
}
vis[u]=true;
}
if(num>1) flag1=false;
while(!Q.empty()){
int u=Q.front();
Q.pop();
for(int i=0;i<gr[u].size();i++){
int v=Find(gr[u][i]);
if(--in[v]==0){
Q.push(v);
}
}
}
for(int i=0;i<n;i++){
if(in[i]){
flag2=false;
break;
}
}
if(flag2==false) return 1;
else if(flag1==false) return 2;
else return 0;
}

int main(){
while(~scanf("%d%d",&n,&m)){
init();
for(int i=1;i<=m;i++){
scanf("%d%s%d",&u[i],op[i],&v[i]);
if(op[i][0]=='=') Union(u[i],v[i]);
}
for(int i=1;i<=m;i++){
int a=Find(u[i]);
int b=Find(v[i]);
if(op[i][0]=='<'){
in[b]++;
gr[a].push_back(b);
}
if(op[i][0]=='>'){
in[a]++;
gr[b].push_back(a);
}
}
int ans=Tuopu();
if(ans==0) printf("OK\n");
else if(ans==1) printf("CONFLICT\n");
else printf("UNCERTAIN\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: