只针对DAG排序
如果有环,序列长度不为n
板子
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<vector> 5 #include<cstring> 6 using namespace std; 7 #define N 100005 8 priority_queue< int,vector<int>,greater<int> > q; 9 vector<int> g[N]; 10 int tot,a[N]; 11 int in[N]; 12 int n,m; 13 bool topo(){ 14 for(int i=1;i<=n;i++) 15 if(in[i]==0)q.push(i); 16 while(!q.empty()){ 17 int u=q.top();q.pop(); 18 a[++tot]=u; 19 for(int i=0;i<g[u].size();i++){ 20 int v=g[u][i]; 21 in[v]--; 22 if(in[v]==0)q.push(v); 23 } 24 } 25 if(tot==n)return 0; 26 else return 1; 27 } 28 int main(){ 29 scanf("%d%d",&n,&m); 30 for(int i=1,x,y;i<=m;i++){ 31 scanf("%d%d",&x,&y); 32 g[x].push_back(y); 33 in[y]++; 34 } 35 if(topo())printf("OMG."); 36 else for(int i=1;i<=n;i++) 37 printf("%d ",a[i]); 38 return 0; 39 }
最长路https://www.luogu.com.cn/problem/P1807
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<vector> 5 #include<utility> 6 #include<cstring> 7 using namespace std; 8 #define N 1000000 9 int n,m,tot; 10 int in[N],dp[N]; 11 bool vis[N]; 12 vector< pair<int,int> > g[N]; 13 queue< int > q; 14 int main(){ 15 scanf("%d%d",&n,&m); 16 for(int i=1,x,y,z;i<=m;i++){ 17 scanf("%d%d%d",&x,&y,&z); 18 g[x].push_back(pair<int,int>(y,z)); 19 in[y]++; 20 } 21 for(int i=1;i<=n;i++){ 22 dp[i]=0; 23 if(in[i]==0)q.push(i); 24 } 25 dp[n]=-1;vis[1]=1; 26 while(!q.empty()){ 27 int u=q.front();q.pop(); 28 for(int i=0;i<g[u].size();i++){ 29 int v=g[u][i].first;in[v]--; 30 if(vis[u]) 31 dp[v]=max(dp[v],dp[u]+g[u][i].second),vis[v]=1; 32 if(in[v]==0)q.push(v); 33 } 34 } 35 printf("%d ",dp[n]); 36 return 0; 37 }
https://www.luogu.com.cn/problem/P1347接近板子
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<vector> 5 #include<algorithm> 6 #include<utility> 7 #include<queue> 8 using namespace std; 9 #define N 150 10 vector<int> g[N]; 11 queue<int> q; 12 bool vis[N],wr,f; 13 int in[N],a[N],inc[N];//copy in 14 int cnt,sum; 15 int n,m; 16 char ch; 17 int tp(){ 18 wr=0;sum=0;f=0; 19 for(int i=1;i<=26;i++){ 20 inc[i]=in[i]; 21 if(!inc[i]&&vis[i]){ 22 if(!f)f=1; 23 else wr=1; 24 q.push(i); 25 a[++sum]=i; 26 } 27 } 28 if(q.empty())return 1; 29 while(q.size()){ 30 int x=q.front();q.pop();f=0; 31 for(int i=0;i<g[x].size();i++){ 32 int v=g[x][i];inc[v]--; 33 if(!inc[v]){ 34 q.push(v);a[++sum]=v; 35 if(!f)f=1; 36 else wr=1; 37 } 38 } 39 } 40 if(cnt!=sum)return 1; 41 if(wr)return 2; 42 return 0; 43 } 44 int main(){ 45 scanf("%d%d",&n,&m); 46 for(int i=1,x,y;i<=m;i++){ 47 cin>>ch;x=ch-64;if(!vis[x]){vis[x]=1;cnt++;} 48 cin>>ch; 49 cin>>ch;y=ch-64;if(!vis[y]){vis[y]=1;cnt++;} 50 g[x].push_back(y);in[y]++; 51 if(tp()==1){ 52 printf("Inconsistency found after %d relations.",i); 53 return 0; 54 } 55 if(sum==n&&!tp()){ 56 printf("Sorted sequence determined after %d relations: ",i); 57 for(int j=1;j<=n;j++) 58 printf("%c",a[j]+64); 59 printf("."); 60 return 0; 61 } 62 } 63 printf("Sorted sequence cannot be determined."); 64 return 0; 65 }
https://www.luogu.com.cn/problem/P1983
解析:未停靠点向已停靠点连边,然后删点删边,统计层数,最后减1;
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define N 1005 5 using namespace std; 6 int in[N],n,m,s; 7 int tp[N][N],a[N],b[N],cnt,ans=0; 8 bool vis[N],is[N]; 9 int main(){ 10 scanf("%d%d",&n,&m); 11 for(int i=1;i<=m;i++){ 12 memset(is,0,sizeof(is)); 13 scanf("%d",&s); 14 for(int j=1;j<=s;j++) 15 scanf("%d",&a[j]),is[a[j]]=1; 16 for(int j=a[1];j<=a[s];j++) 17 if(!is[j]) 18 for(int k=1;k<=s;k++) 19 if(!tp[j][a[k]])tp[j][a[k]]=1,in[a[k]]++; 20 } 21 do{ 22 cnt=0; 23 for(int i=1;i<=n;i++) 24 if(!in[i]&&!vis[i]) 25 b[++cnt]=i,vis[i]=1; 26 for(int i=1;i<=cnt;i++) 27 for(int j=1;j<=n;j++) 28 if(tp[b[i]][j])tp[b[i]][j]=0,in[j]--; 29 ans++; 30 }while(cnt); 31 printf("%d",ans-1); 32 return 0; 33 }
骑士bzoj1471 https://www.luogu.com.cn/problem/T123920
并未想透。。。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int MAXN = 205; 4 int n, m, d[MAXN], fir[MAXN], to[MAXN*MAXN], nxt[MAXN*MAXN], cnt; 5 inline void Add(int u, int v) { to[++cnt] = v, nxt[cnt] = fir[u], fir[u] = cnt, ++d[v]; } 6 int topo[MAXN], id[MAXN], cur; //topo为拓扑序,id为topo的反函数 7 long long f[MAXN][MAXN], g[MAXN]; 8 queue<int> q; 9 int main () 10 { 11 scanf("%d%d", &n, &m); 12 for(int i = 1, x, y; i <= m; ++i) 13 scanf("%d%d", &x, &y), Add(x, y); 14 for(int i = 1; i <= n; ++i) if(!d[i]) q.push(i); 15 while(q.size() )//拓扑排序 16 { 17 int u = q.front();q.pop(); 18 id[topo[u] = ++cur] = u; 19 for(int i = fir[u]; i; i = nxt[i]) 20 if(--d[to[i]] == 0) q.push(to[i]); 21 } 22 23 for(int i = 1, u; i <= n; ++i) 24 { 25 u = id[i]; f[u][u] = 1; 26 for(int j = i, v; j <= n; ++j) 27 { 28 v = id[j]; 29 for(int k = fir[v]; k; k = nxt[k]) f[u][to[k]] += f[u][v]; 30 } 31 } 32 int a, b, c, d; 33 scanf("%d%d%d%d", &a, &b, &c, &d); 34 for(int i = 1, u; i <= n; ++i) 35 { 36 u = id[i]; 37 g[u] = f[a][u] * f[c][u]; 38 for(int j = 1, v; j < i; ++j) 39 { 40 v = id[j]; 41 g[u] -= g[v] * f[v][u] * f[v][u]; 42 } 43 } 44 long long ans = f[a][b] * f[c][d]; 45 for(int i = 1, u; i <= n; ++i) 46 { 47 u = id[i]; 48 ans -= g[u] * f[u][b] * f[u][d]; 49 } 50 printf("%lld ", ans); 51 return 0; 52 }
https://www.luogu.com.cn/problem/P4316
逆推???
已知n到n的路径长度期望一定是0,所以倒着推(倒着连边即可)
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<vector> using namespace std; #define N 100005 int n,in[N],c[N],m; double dp[N]; vector < pair<int,int> > g[N]; queue<int>q; bool vis[N]; int main(){ scanf("%d%d",&n,&m); for(int i=1,x,y,z;i<=m;i++){ scanf("%d%d%d",&x,&y,&z); g[y].push_back(pair<int,int>(x,z)); in[x]++;c[x]++; } for(int i=1;i<=n;i++){ dp[i]=0; if(!in[i])q.push(i); } vis[1]=1; while(!q.empty()){ int u=q.front();q.pop(); for(int i=0;i<g[u].size();i++){ int v=g[u][i].first,w=g[u][i].second; dp[v]+=dp[u]+w,vis[v]=1; in[v]--; if(in[v]==0){ dp[v]/=c[v];q.push(v); } } } printf("%.2lf ",dp[1]); return 0; }