Kattis-Chess Tournament(有向图判环)

题目链接:点击打开链接

题目大意:
给定一些标号,与标号之间的大小关系,判断所有给出的关系是否能同时成立。
解题思路:
其实看到题目就觉得是一个判断是否存在环的问题,但是有点区别就是点与点之间可以有相等的关系,这样的话就貌似不好直接判环:我当时是想非等于关系用单向边连接,而相等关系用双向边连接,然而实际上没什么卵用,等于关系直接成环了...。后面看了标程才知道自己的理解还是很肤浅啊:相等的关系其级别相同,那么我们把所有在同一个级别的点标一个编号,把所有的点重新标号后,根据原来点与点之间的关系在新的编号之间连边。假如有这样的一些关系:1=2=3=4,5=6=7,2>5,3>7,6>2,首先编号:(1,2,3,4)在一个级别,编号为1,(5,6,7)在一个级别,标号为2,则2>5,3>7,6>2 分别为1->2,1->2,2->1,其他情况以此类推。可以想到这样建成的一个新的图,就可以直接进行判环了。
代码:
#include<iostream>
#include<string>
#include<vector>
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=5e4+10;
vector<int>equ[maxn];
vector<int>gre[maxn];
vector<int>Gra[maxn];
int vis[maxn];
int Newlv[maxn];
int n,m;
void Getlv(int u,int lv){
    if(vis[u])return;
    Newlv[u]=lv;
    vis[u]=1;
    int sz=equ[u].size();
    for(int i=0;i<sz;i++){
        int v=equ[u][i];
        Getlv(v,lv);
    }
}
int ok=1;
bool Top_sort(int u){
    vis[u]=-1;
    for(int i=0;i<Gra[u].size();i++){
        int v=Gra[u][i];
        if(vis[v]==-1)return false;
        else if(!vis[v]&&!Top_sort(v))return false;
    }
    vis[u]=1;
    return true;
}
int main(){
    cin.tie(0);
    ios_base::sync_with_stdio(0);
 //   freopen("in.txt","r",stdin);
    int x,y;
    char ch;
    cin>>n>>m;
    for(int i=0;i<m;i++){
        cin>>x>>ch>>y;
        if(ch=='='){
            equ[x].push_back(y);
            equ[y].push_back(x);
        }
        else gre[x].push_back(y);
    }
    int lv=0;
    for(int i=0;i<n;i++){
        if(!vis[i]){
            Getlv(i,lv);++lv;
        }
    }
    for(int i=0;i<n;i++){
        int sz=gre[i].size();
        for(int j=0;j<sz;j++){
            int k=gre[i][j];
            int u=Newlv[i],v=Newlv[k];
            Gra[u].push_back(v);
        }
    }
    memset(vis,0,sizeof vis);
    for(int i=0;i<lv;i++){
        if(!vis[i]){
            if(!Top_sort(i)){ok=0;break;}
        }
    }
    if(ok)cout<<"consistent\n";
    else cout<<"inconsistent\n";
    return 0;
}

其实做这个题以前并没有很仔细地去看拓扑排序,然后每次就直接抄模板。大概看了题解之后,就直接DFS去搜了一遍——WA...,然后想想才明白有向图判环和无向图判环的区别:一个可以重复搜到同一个点,只要这个点已经出栈了;一个只要搜到同一个点,就可以判断有环。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值