题意:
给出 m 条有向边,组成有向无环图,输出一个 1 到 n 组成的排列,每个数只能出现一次,表示每个点的标号。如果有边 (u,v)(u,v) 那么 labelu<labelvlabelu<labelv 。要求最后字典序尽可能小。
solution:
拓扑排序的变形。
这题要统计的是每个点的出度,比如说某个点出度为 0 ,那么它的标号一定很大(因为它不需要比别的点小了),又要求字典序最小,对于初始图,那么出度为 0 的点且序号最大的点的标号一定为 n。优先队列维护下(最大值优先),如果某个点的标号确定了,那么删除所有连向这个点的边,更新出度。、
搞清楚小的尽量靠前和靠前的尽量小的区别
反向建图:
1 /************************************************************************* 2 > File Name: a.cpp 3 > Author: QWX 4 > Mail: 5 > Created Time: 2018/11/11 9:43:08 6 ************************************************************************/ 7 8 9 //{{{ #include 10 #include<iostream> 11 #include<cstdio> 12 #include<algorithm> 13 #include<vector> 14 #include<cmath> 15 #include<queue> 16 #include<map> 17 #include<set> 18 #include<string> 19 #include<cstring> 20 #include<complex> 21 #include<cassert> 22 //#include<bits/stdc++.h> 23 #define vi vector<int> 24 #define pii pair<int,int> 25 #define mp make_pair 26 #define pb push_back 27 #define fi first 28 #define se second 29 #define pw(x) (1ll << (x)) 30 #define sz(x) ((int)(x).size()) 31 #define all(x) (x).begin(),(x).end() 32 #define rep(i,l,r) for(int i=(l);i<(r);i++) 33 #define per(i,r,l) for(int i=(r);i>=(l);i--) 34 #define FOR(i,l,r) for(int i=(l);i<=(r);i++) 35 #define cl(a,b) memset(a,b,sizeof(a)) 36 #define fastio ios::sync_with_stdio(false);cin.tie(0); 37 #define lson l , mid , ls 38 #define rson mid + 1 , r , rs 39 #define INF 0x3f3f3f3f 40 #define LINF 0x3f3f3f3f3f3f3f3f 41 #define ll long long 42 #define ull unsigned long long 43 #define dd(x) cout << #x << " = " << (x) << "," 44 #define de(x) cout << #x << " = " << (x) << " " 45 #define endl " " 46 using namespace std; 47 //}}} 48 49 const int N=1e5+7; 50 int in[N],ans[N]; 51 vi G[N]; 52 int n,m; 53 54 int main() 55 { 56 priority_queue<int,vector<int>,greater<int> > Q; 57 cin>>n>>m; 58 rep(i,0,m){ 59 int u,v; cin>>u>>v; 60 in[v]++; 61 G[u].pb(v); 62 } 63 FOR(i,1,n)if(!in[i])Q.push(i); 64 // FOR(i,1,3)dd(out[i]);cout<<endl; 65 int t=0; 66 while(!Q.empty()){ 67 int u=Q.top();Q.pop(); 68 ans[u]=++t; 69 for(auto v:G[u])if(--in[v]==0)Q.push(v); 70 } 71 FOR(i,1,n)cout<<ans[i]<<(i==n?' ':' '); 72 return 0; 73 } 74 /* 75 4 2 76 4 1 77 2 3 78 */
正向建图(错误的做法):
这组数据过不了:
4 2
4 1
2 3
1 /************************************************************************* 2 > File Name: a.cpp 3 > Author: QWX 4 > Mail: 5 > Created Time: 2018/11/11 9:43:08 6 ************************************************************************/ 7 8 9 //{{{ #include 10 #include<iostream> 11 #include<cstdio> 12 #include<algorithm> 13 #include<vector> 14 #include<cmath> 15 #include<queue> 16 #include<map> 17 #include<set> 18 #include<string> 19 #include<cstring> 20 #include<complex> 21 #include<cassert> 22 //#include<bits/stdc++.h> 23 #define vi vector<int> 24 #define pii pair<int,int> 25 #define mp make_pair 26 #define pb push_back 27 #define fi first 28 #define se second 29 #define pw(x) (1ll << (x)) 30 #define sz(x) ((int)(x).size()) 31 #define all(x) (x).begin(),(x).end() 32 #define rep(i,l,r) for(int i=(l);i<(r);i++) 33 #define per(i,r,l) for(int i=(r);i>=(l);i--) 34 #define FOR(i,l,r) for(int i=(l);i<=(r);i++) 35 #define cl(a,b) memset(a,b,sizeof(a)) 36 #define fastio ios::sync_with_stdio(false);cin.tie(0); 37 #define lson l , mid , ls 38 #define rson mid + 1 , r , rs 39 #define INF 0x3f3f3f3f 40 #define LINF 0x3f3f3f3f3f3f3f3f 41 #define ll long long 42 #define ull unsigned long long 43 #define dd(x) cout << #x << " = " << (x) << "," 44 #define de(x) cout << #x << " = " << (x) << " " 45 #define endl " " 46 using namespace std; 47 //}}} 48 49 const int N=1e5+7; 50 int out[N],ans[N]; 51 vi G[N]; 52 int n,m; 53 54 int main() 55 { 56 priority_queue<int> Q; 57 cin>>n>>m; 58 rep(i,0,m){ 59 int u,v; cin>>u>>v; 60 G[v].pb(u); 61 out[u]++; 62 } 63 FOR(i,1,n)if(!out[i])Q.push(i); 64 // FOR(i,1,3)dd(out[i]);cout<<endl; 65 int nn=n; 66 while(!Q.empty()){ 67 int u=Q.top();Q.pop(); 68 // de(u); 69 ans[u]=nn--; 70 for(auto v:G[u])if(--out[v]==0)Q.push(v); 71 } 72 FOR(i,1,n)cout<<ans[i]<<(i==n?' ':' '); 73 return 0; 74 }