日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CodeForces - 1547G How Many Paths?(强联通缩点+拓扑)

發布時間:2024/4/11 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CodeForces - 1547G How Many Paths?(强联通缩点+拓扑) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:點擊查看

題目大意:給出一張有向圖,無重邊,有環,現在需要判斷每個點和點 111 的關系:

  • 000:點 111 無法到達點 uuu
  • 111:點 111 到點 uuu 有且僅有一條路徑
  • 222:點 111 到點 uuu 有大于一條路徑,但是路徑數是有限的
  • ?1-1?1:點 111 到點 uuu 的路徑數是無限的
  • 題目分析:直接強聯通縮點將原圖轉換成一個 DAGDAGDAG,然后直接拓撲就可以了,邊拓撲邊轉移 dpdpdp,也就是答案,dpdpdp 的方程自己分成 4?4=164*4=164?4=16 種情況討論一下,最后再合起來就可以了,不是很難

    需要注意的是對于 ?1-1?1 的判斷和轉移

    對于本題學到了一個很神奇的知識點,強聯通縮點后,序號的逆序就是拓撲序,這樣一來就不需要再記錄入度再開隊列拓撲了,非常的方便

    代碼:

    // Problem: G. How Many Paths? // Contest: Codeforces - Codeforces Round #731 (Div. 3) // URL: https://codeforces.com/contest/1547/problem/G // Memory Limit: 512 MB // Time Limit: 4000 ms // // Powered by CP Editor (https://cpeditor.org)// #pragma GCC optimize(2) // #pragma GCC optimize("Ofast","inline","-ffast-math") // #pragma GCC target("avx,sse2,sse3,sse4,mmx") #include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> #define lowbit(x) x&-x using namespace std; typedef long long LL; typedef unsigned long long ull; template<typename T> inline void read(T &x) {T f=1;x=0;char ch=getchar();while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();x*=f; } template<typename T> inline void write(T x) {if(x<0){x=~(x-1);putchar('-');}if(x>9)write(x/10);putchar(x%10+'0'); } const int inf=0x3f3f3f3f; const int N=1e6+100;const int M=1e6+100;struct Egde {int to,next; }edge1[M],edge2[M];int head1[N],head2[N],low[N],dfn[N],c[N],Stack[N],num,cnt,cnt2,cnt1,dcc,n,m,top,dp[N];bool ins[N],circle[N];vector<int>scc[N];void addedge1(int u,int v) {edge1[cnt1].to=v;edge1[cnt1].next=head1[u];head1[u]=cnt1++; }void addedge2(int u,int v) {edge2[cnt2].to=v;edge2[cnt2].next=head2[u];head2[u]=cnt2++; }void tarjan(int u) {dfn[u]=low[u]=++num;Stack[++top]=u;ins[u]=true;for(int i=head1[u];i!=-1;i=edge1[i].next){int v=edge1[i].to;if(!dfn[v]){tarjan(v);low[u]=min(low[u],low[v]);}else if(ins[v])low[u]=min(low[u],dfn[v]);}if(dfn[u]==low[u]){cnt++;int v;do{v=Stack[top--];ins[v]=false;c[v]=cnt;scc[cnt].push_back(v);}while(u!=v);} }void solve() {for(int i=1;i<=n;i++)//縮點 if(!dfn[i])tarjan(i); }void build()//縮點+連邊 {solve();for(int i=1;i<=n;i++){for(int j=head1[i];j!=-1;j=edge1[j].next){int u=i;int v=edge1[j].to;if(c[u]!=c[v])addedge2(c[u],c[v]);}} }void init(int n) {for(int i=0;i<=n;i++)scc[i].clear();top=cnt=cnt1=cnt2=num=dcc=0;memset(circle,false,n+5);memset(dp,0,sizeof(int)*(n+5));memset(head2,-1,sizeof(int)*(n+5));memset(head1,-1,sizeof(int)*(n+5));memset(low,0,sizeof(int)*(n+5));memset(dfn,0,sizeof(int)*(n+5));memset(c,0,sizeof(int)*(n+5));memset(ins,false,n+5); } void topo() {dp[c[1]]=1;for(int u=cnt;u>=1;u--) {if(dp[u]>0&&circle[u]) {dp[u]=-1;}if(dp[u]==0) {continue;}for(int i=head2[u];i!=-1;i=edge2[i].next) {int v=edge2[i].to;if(dp[v]==-1) {continue;}if(dp[u]==-1) {dp[v]=-1;} else if(dp[u]==1) {if(dp[v]==0) {dp[v]=1;} else if(dp[v]==1) {dp[v]=2;}} else if(dp[u]==2) {dp[v]=2;}}} } int main() { #ifndef ONLINE_JUDGE // freopen("data.in.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);int w;cin>>w;while(w--) {vector<pair<int,int>>node;read(n),read(m);init(n);while(m--) {int u,v;read(u),read(v);addedge1(u,v);node.push_back({u,v});}build();for(auto it:node) {int u=it.first,v=it.second;if(c[u]==c[v]) {circle[c[u]]=true;}}topo();for(int i=1;i<=n;i++) {printf("%d ",dp[c[i]]);}puts("");}return 0; } 超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生

    總結

    以上是生活随笔為你收集整理的CodeForces - 1547G How Many Paths?(强联通缩点+拓扑)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。