bzoj5280/luogu4376 MilkingOrder (二分答案+拓扑序)

二分答案建图,然后判环,就可以了。

字典序输出的话,只要做拓扑序的时候用优先队列来维护就可以了。

(其实判环也可以用拓扑序...)

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<vector>
 6 #include<queue>
 7 #include<set>
 8 #include<ctime>
 9 #define LL long long
10 using namespace std;
11 const int maxn=100010,maxm=50050,summ=200020;
12 
13 LL rd(){
14     LL x=0;char c=getchar();int neg=1;
15     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
16     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
17     return x*neg;
18 }
19 
20 int N,M;
21 int eg[summ][3],egh[maxn],ect,ine[maxn];
22 bool flag[maxn],instk[maxn],ans;
23 
24 inline void adeg(int a,int b,int m){
25     eg[++ect][0]=b;eg[ect][1]=egh[a];eg[ect][2]=m;egh[a]=ect;
26 }
27 
28 bool dfs(int x,int m){
29     flag[x]=instk[x]=1;bool re=0;
30     for(int i=egh[x];i!=-1;i=eg[i][1]){
31         if(eg[i][2]>m) continue;
32         if(!flag[eg[i][0]]) re|=dfs(eg[i][0],m);
33         else if(instk[eg[i][0]]) return 1;
34     }instk[x]=0;return re;
35 }
36 
37 int main(){
38     //freopen("4376.in","r",stdin);
39     int i,j,k;
40     N=rd(),M=rd();memset(egh,-1,sizeof(egh));
41     for(i=1;i<=M;i++){int last=0;
42         for(j=rd();j;j--){
43             k=rd();if(last) adeg(last,k,i);last=k;
44         }
45     }
46     int l=1,r=M;
47     while(l<=r){
48         memset(instk,0,sizeof(instk));memset(flag,0,sizeof(flag));
49         int m=l+r>>1;bool b=0;
50         for(i=1;i<=N;i++) if(!flag[i]) b|=dfs(i,m);
51         if(b) r=m-1;
52         else{
53             l=m+1;
54         }
55     }l--;
56     for(i=1;i<=ect;i++){
57         if(eg[i][2]<=l) ine[eg[i][0]]++;
58     }priority_queue<int,vector<int>,greater<int> > q;
59     for(i=1;i<=N;i++) if(!ine[i]) q.push(i);
60     while(!q.empty()){
61         int p=q.top();q.pop();printf("%d ",p);
62         for(i=egh[p];i!=-1;i=eg[i][1]){
63             if(eg[i][2]>l) continue;
64             int b=eg[i][0];ine[b]--;
65             if(!ine[b]) q.push(b);
66         }
67     }
68     return 0;
69 }
原文地址:https://www.cnblogs.com/Ressed/p/9581196.html