数据结构和算法分析

hdoj1811(拓扑排序和并查集)

2018-06-13  本文已影响1人  周九九丶

题目大意

知识背景

AC代码

#include <iostream>
#include <queue>
using namespace std;

const int MAX_E = 20010;
const int MAX_V = 10010;

//graph presentation
struct Edge{
    int to;
    int next;
};
struct Edge edges[MAX_E];
int head[MAX_V];
int cnt;

//unionfind
int p[MAX_V];//p[i] means the root if node i
int r[MAX_V];//r[i] means the depth of the tree where node i is in

//graph information
int vNum;
int eNum;

//topological sort
int inDegree[MAX_V];//inDegree[i] means the inDegreee of node i
int n;//n means the num of nodes whose final inDegree is 0
int total;//total means the num of different ranks

//input
int a[MAX_E];
int b[MAX_E];
char relation[MAX_E];

//output
bool conflictFlag;
bool uncertainFlag;

//return the root of x
int Find(int x){
    if(x == p[x]) return p[x];
    else return p[x] = Find(p[x]);
}
//union the trees where x and y are in
void Union(int x, int y){
    int xRoot = Find(x);
    int yRoot = Find(y);Find;
    if(r[xRoot] < r[yRoot]) p[xRoot] = yRoot;
    else{
        p[yRoot] = xRoot;
        if(r[xRoot] == r[yRoot]) r[xRoot]++;
    }
}
//return whether x and y are in the same tree
bool sameRoot(int x, int y){
    return Find(x) == Find(y);
}
//topological sort
void toposort(){
    queue<int> q;
    while(!q.empty()) q.pop();
    
    //the first time to push nodes whose inDegree is 0
    for(int i = 0; i < vNum; i++){
        if(inDegree[i] == 0 && p[i] == i) q.push(i);
    }

    while(!q.empty()){
        //if there are more than 1 node whose inDegree is 0 in the same time
        //we say "UNCERTAIN"
        if(q.size() > 1) uncertainFlag = false;
        int u = q.front(); q.pop();
        n++;
        //update neighbor's inDegree
        for(int i = head[u]; i != -1; i = edges[i].next){
            int v = edges[i].to;
            inDegree[v]--;
            if(inDegree[v] == 0) q.push(v);
        }   
    }
    if(n != total) conflictFlag = false;
}

void addEdge(int u, int v){
    edges[cnt].to = v;
    edges[cnt].next = head[u];
    head[u] = cnt++;
}

void init(){
    total = vNum;
    cnt = 0;
    n = 0;
    conflictFlag = true;
    uncertainFlag = true;
    for(int i = 0; i < vNum; i++){
        head[i] = -1;
        p[i] = i;
        r[i] = 0;
        inDegree[i] = 0;
    }
}

int main(){
    while(scanf("%d %d", &vNum, &eNum) == 2){
        init();
        for(int i = 0; i < eNum; i++){
            scanf("%d %c %d", &a[i], &relation[i], &b[i]);
            //when relation[i] == '=' and a[i] b[i] are not in the same tree
            //Union the trees where a[i] and b[i] are in
            if(relation[i] == '=' && !sameRoot(a[i], b[i])){
                Union(a[i], b[i]);
                total--;
            }
        }
        for(int i = 0; i < eNum; i++){
            int x = Find(a[i]);
            int y = Find(b[i]);
            //when relation[i] == '>', add a edge from a[i]'s root to b[i]'s root 
            if(relation[i] == '>'){
                addEdge(x, y);
                inDegree[y]++;
            }
            //when relation[i] == '<', add a edge from b[i]'s root to a[i]'s root 
            if(relation[i] == '<'){
                addEdge(y, x);
                inDegree[x]++;
            }
        }
        toposort();
        if(conflictFlag && uncertainFlag) printf("OK\n");
        else if(!conflictFlag) printf("CONFLICT\n");
        else printf("UNCERTAIN\n");
    }
    return 0;
}
上一篇 下一篇

猜你喜欢

热点阅读