Topological sorting --CodeForces-645D

Topic Link

Title meaning

There is a robot competition, as long as a can beat b, b c can defeat, a defeat will be able to c

Then gives the results of a bunch of race, if you can not get all the robots only combat power rankings, outputs -1

If possible, use at least the first few races to get the result, the output of the minimum number of matches

Topic analysis

-1 are output using a topological sort, if the number of teams is not equal to the number of the robot at a time or two or more queue has a zero-degree point

And if so, to find the minimum number of matches

If you add an edge with a topological sorting, then obviously time out

It provides two methods here

(1) you have found topological sort of relationship between every two points are given in the title of it

For example, the sequence 4-2-1-3, will give 2,2 4 beat beat beat 1,1 3

And we have to do is to record every game the necessary outcome of the match in the topological sorting

Then look at the input, the whole game when necessary arise, get a minimum number of matches

(2) can be half the answer, look for the least number of times in the input but also to the number of topological sort of meet

Topic Code

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+7;
int in[maxn],sum,n,m,a[maxn],b[maxn],head[maxn],tot,copyin[maxn];
bool flag;
int fa[maxn],cnt;
struct edge{
    int to,next;
}e[maxn];
bool topusort(){
    queue<int>q;
//    for(int i=1;i<=n;i++)
//        copyin[i]=in[i];
    for(int i=1;i<=n;i++)
        if(!in[i])q.push(i);
    int num=0;
    while(!q.empty()){
        if(q.size()>1)return false;
        int u=q.front();q.pop();
        num++;
        for(int i=head[u];i!=-1;i=e[i].next){
            int v=e[i].to;
            if(--in[v]==0){
                q.push(v);
                fa[v]=u;
                cnt++;
            }
        }
    }return num==n;
}
void add(int u,int v){
    e[tot].to=v;
    e[tot].next=head[u];
    head[u]=tot++;
}
int main(){
    scanf("%d%d",&n,&m);
    memset(head,-1,sizeof(head));
    int k=0;
//    flag=false;
    for(int i=1;i<=m;i++){
        scanf("%d%d",&a[i],&b[i]);
        add(a[i],b[i]);
        in[b[i]]++;
    }
    if(!topusort())printf("-1\n");
    else{
        for(int i=1;i<=m;i++){
            if(fa[b[i]]==a[i]){
                cnt--;
                if(cnt==0){
                    printf("%d\n",i);
                    break;
                }
            }
        }
    }
    return 0;
}
The first practice
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
typedef long long LL;
const int maxn=1e5+7;
int head[maxn],tot,in[maxn];
struct edge{
    int to,next;
}e[maxn];
void add(int u,int v){
    e[tot].to=v;
    e[tot].next=head[u];
    head[u]=tot++;
}
int n,m,a[maxn],b[maxn];
bool topusort(int nn){
    memset(head,-1,sizeof(head));
    memset(in,0,sizeof(in));
    tot=0;
    for(int i=1;i<=nn;i++){
        add(a[i],b[i]);
        in[b[i]]++;
    }
    queue<int>q;
    for(int i=1;i<=n;i++)
        if(in[i]==0)q.push(i);
    while(!q.empty()){
        if(q.size()>1)return false;
        int u=q.front();q.pop();
        for(int i=head[u];i!=-1;i=e[i].next){
            int v=e[i].to;
            if(--in[v]==0)q.push(v);
        }
    }
//    cout<<sum<<endl;
    return true;
//    return sum==n;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
        scanf("%d%d",&a[i],&b[i]);
    int low=1,high=m;
    int ans=-1;
    while(low<=high){
        int mid=(low+high)>>1;
        if(topusort(mid)){
            ans=mid;
            high=mid-1;
        }
        else low=mid+1;
    }
    printf("%d\n",ans);
    return 0;
}
The second approach

I do not know why, I put in the array defined in the topology, with its default value, the result will be wrong

Guess you like

Origin www.cnblogs.com/helman/p/11291727.html