hdoj 1811

此题是一个并查集与拓扑排序结合的题

1.把相等的点并合为一个集

2.统计合并后总共有几个点

3.通过拓扑排序来判断属于那种情况:若又一次S.size()>1,则说明不确定;若cnt<num则存在环路;以上两种情况都不存在则说明ok

#include<iostream>
#include<vector>
#include<stack>
#include<string.h>
#include<algorithm>
using namespace std;

#define maxn 10010
typedef struct Point
{
 int x,y;
}Point;
Point p[maxn];
vector<int>p_link[maxn];
int bin[maxn],index[maxn];
int n;

int find(int x)
{
 while(x!=bin[x]) x=bin[x];
 return x;
}

void TopologicalSort()
{
 int i,u,v,num=0,cnt=0,flag=0;
 stack<int>S;
 for(i=0;i<n;i++)/////统计不想等的个数
 {
  if(bin[i]!=i) continue;
  num++;
  if(index[i]==0) S.push(i);///////统计度数为零的点
 }
 while(!S.empty())
 {
  if(S.size()>1) flag=1;
  u=S.top(),S.pop(),cnt++;
  for(i=0;i<p_link[u].size();i++)
  {
   v=p_link[u][i];
   if(--index[v]==0) S.push(v);
  }
 }
 if(cnt<num) printf("CONFLICT\n");//////存在回路矛盾
 else if(flag) printf("UNCERTAIN\n");
 else printf("OK\n");
}

int main()
{
 int m,i;
 char ch[2];
 while(scanf("%d%d",&n,&m)==2)
 {
  int cnt=0,x,y;
  memset(index,0,sizeof(index));
  for(i=0;i<n;i++) p_link[i].clear(),bin[i]=i;
  for(i=1;i<=m;i++)
  {
   scanf("%d%s%d",&x,&ch,&y);
   if(ch[0]=='>')
    p[cnt].x=x,p[cnt++].y=y;
   else if(ch[0]=='<')
    p[cnt].x=y,p[cnt++].y=x;
   else/////////////把相等的合并在一起
   {
    x=find(x); y=find(y);
    if(x>y)
     bin[y]=x;
    else
     bin[x]=y;
   }
  }
  for(i=0;i<cnt;i++)
  {
   x=find(p[i].x);
   y=find(p[i].y);
   index[y]++;
   p_link[x].push_back(y);
  }
  TopologicalSort();
 }
 return 0;
}

 

posted @ 2012-02-19 21:48  forgood  阅读(227)  评论(0编辑  收藏  举报