Codeforces Round #731 (Div. 3) G. How Many Paths? dfs + 拓扑 + 思维
傳送門
題意:
給你一張nnn個(gè)點(diǎn)mmm條邊的圖,讓你對(duì)每個(gè)點(diǎn)確定一個(gè)編號(hào),規(guī)則如下:
(1)(1)(1) 對(duì)于不能到的點(diǎn)編號(hào)為000。
(2)(2)(2) 對(duì)于只有一條路徑能到這個(gè)點(diǎn)的點(diǎn)編號(hào)為111。
(3)(3)(3) 對(duì)于有不止一條路徑能到這個(gè)點(diǎn)的點(diǎn)編號(hào)為222。
(4)(4)(4) 對(duì)于有無(wú)數(shù)條路徑能到這個(gè)點(diǎn)的點(diǎn)編號(hào)為333。
思路:
考慮一次dfsdfsdfs能得到什么東西,我們可以通過(guò)一次dfsdfsdfs確定下來(lái)不能到達(dá)的點(diǎn),還可以確定只有一條路徑的點(diǎn),但是不能確定所有不止一條路徑的點(diǎn),因?yàn)橛锌赡艿侥硞€(gè)點(diǎn)路徑有若干條,這個(gè)點(diǎn)能到的點(diǎn)應(yīng)該也可以有兩條路徑到達(dá),但是如果只跑一次是確定不下來(lái)的,所以我們給這些點(diǎn)打個(gè)標(biāo)記,讓后再跑一次dfsdfsdfs,這樣就可以確定下來(lái)所有0,1,20,1,20,1,2的點(diǎn)了。
考慮?1-1?1的點(diǎn)怎么確定,看到環(huán)應(yīng)該可以想到拓?fù)渑判?#xff0c;所以我們把111號(hào)點(diǎn)仍隊(duì)列里面,讓后跑拓?fù)?#xff0c;不能到的點(diǎn)就是?1-1?1點(diǎn),因?yàn)橛协h(huán)的話會(huì)類似一個(gè)瓶頸卡住他下面的點(diǎn)以及環(huán)上的點(diǎn),所以不能到的點(diǎn)即為可以經(jīng)過(guò)環(huán)到達(dá)的點(diǎn),直接標(biāo)記為?1-1?1即可。
但是這個(gè)題細(xì)節(jié)很多很多,比如如果一開(kāi)始111就在環(huán)里,我們這個(gè)時(shí)候全部賦值為?1-1?1即可,需要特判一下。還有需要將不能經(jīng)過(guò)的點(diǎn)能到達(dá)的點(diǎn)的度數(shù)減去,因?yàn)槿绻蝗サ?#xff0c;拓?fù)渑判蜻@些點(diǎn)就會(huì)被認(rèn)為是環(huán)能經(jīng)過(guò)的點(diǎn),是不合理的。
// 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("Ofast,no-stack-protector,unroll-loops,fast-math") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native") //#pragma GCC optimize(2) #include<cstdio> #include<iostream> #include<string> #include<cstring> #include<map> #include<cmath> #include<cctype> #include<vector> #include<set> #include<queue> #include<algorithm> #include<sstream> #include<ctime> #include<cstdlib> #include<random> #include<cassert> #define X first #define Y second #define L (u<<1) #define R (u<<1|1) #define pb push_back #define mk make_pair #define Mid ((tr[u].l+tr[u].r)>>1) #define Len(u) (tr[u].r-tr[u].l+1) #define random(a,b) ((a)+rand()%((b)-(a)+1)) #define db puts("---") using namespace std;//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); } //void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); } //void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> PII;const int N=1000010,mod=1e9+7,INF=0x3f3f3f3f; const double eps=1e-6;int n,m; vector<int>v[N]; int id[N],st[N],d[N];void dfs1(int u) {id[u]=1; st[u]=1;for(auto x:v[u]) {if(st[x]) {id[x]=2;continue;}dfs1(x);} }void dfs2(int u,int now) {st[u]=1;if(id[u]==2) now=2;id[u]=now;for(auto x:v[u]) {if(st[x]) continue;dfs2(x,now);} }void topsort() {if(id[1]==2) {for(int i=1;i<=n;i++) if(id[i]) id[i]=-1;return;}queue<int>q;for(int i=1;i<=n;i++) st[i]=0;q.push(1);while(q.size()) {int u=q.front(); q.pop();st[u]=1;for(auto x:v[u]) {if(--d[x]==0) q.push(x);}}for(int i=1;i<=n;i++) if(!st[i]&&id[i]) id[i]=-1; }int main() { // ios::sync_with_stdio(false); // cin.tie(0);int _; scanf("%d",&_);while(_--) {scanf("%d%d",&n,&m);for(int i=1;i<=n;i++) id[i]=st[i]=d[i]=0,v[i].clear();for(int i=1;i<=m;i++) {int a,b; scanf("%d%d",&a,&b);d[b]++; v[a].pb(b);}dfs1(1);for(int i=1;i<=n;i++) if(!st[i]) {for(auto x:v[i]) d[x]--;}for(int i=1;i<=n;i++) st[i]=0;dfs2(1,1);topsort();for(int i=1;i<=n;i++) printf("%d ",id[i]);puts("");}return 0; } /**/總結(jié)
以上是生活随笔為你收集整理的Codeforces Round #731 (Div. 3) G. How Many Paths? dfs + 拓扑 + 思维的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 滴滴第三季度营收增长25%至514亿元
- 下一篇: 录屏直播软件 OBS Studio 30