您的位置:首页 > 其它

HDU 1811 Rank of Tetris(拓扑排序+并查集)

2013-04-11 12:31 561 查看
如果A==B把A和B归到同一个集合中,然后把这个集合当作一个单位顶点.

然后进行拓扑排序

#include <iostream>
#include <cstdio>
#include <memory.h>
#include <queue>
#include <vector>
using namespace std;
const int maxn=10010;
struct edge
{
int v,next;
}e[maxn*2];
int head[maxn],ind[maxn],id[maxn],size[maxn],n,m;
int L[maxn*2],R[maxn*2];
char O[maxn*2];

int find(int p){
return p==id[p]?p:id[p]=find(id[p]);
}

bool uni(int p,int q){
int pp=find(p),pq=find(q);
if(pp==pq)return false;
if(size[pp]>size[pq]){
id[pq]=pp;
size[pp]+=size[pq];
}else{
id[pp]=pq;
size[pq]+=size[pp];
}
return true;
}

void addEdge(int ecnt,int u,int v){
e[ecnt].v=v;
e[ecnt].next=head[u];
head[u]=ecnt;
}

void topSort(int & cnt,int &flag){
queue<int>q;
for (int i=0;i<n;++i){
if(ind[i]==0&&i==find(i))//入度为0 并且自己是一个集合
q.push(i);
}
while (q.size())
{
if(q.size()>1)
flag=1;//表示信息不完整
int t=q.front();q.pop();
cnt--;
for (int ne=head[t];ne!=-1;ne=e[ne].next){
if(--ind[e[ne].v]==0){
q.push(e[ne].v);
}
}
}
}

int main(){
while (scanf("%d%d",&n,&m)==2){
vector<int>equals;
for (int i=0;i<n;++i){
ind[i]=0;
id[i]=i;
size[i]=1;
head[i]=-1;
}
int f=0,cnt=n;
for (int i=0;i<m;++i){
int u,v;
char ch;
scanf("%d %c %d",&L[i],&O[i],&R[i]);
if(O[i]=='='){
if(uni(L[i],R[i]))
cnt--;
}
}
for (int i=0;i<m;++i){
if(O[i]=='=')continue;
int pp=find(L[i]),pq=find(R[i]);
if(pp==pq){//同属同一个集合不能相连
f=true;
}
if(O[i]=='>'){
addEdge(i,pp,pq);
ind[pq]++;
}else{
addEdge(i,pq,pp);
ind[pp]++;
}
}
if(f){
printf("CONFLICT\n");
continue;
}
topSort(cnt,f);
if(cnt>0){//如果还有点未决,说明有环
printf("CONFLICT\n");
}else if(f){//说明同时存在两个0度的定点,关系不确定
printf("UNCERTAIN\n");
}
else{
printf("OK\n");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: