Usaco Training Section 4.3 Street Race
阿新 • • 發佈:2018-11-12
題意真的挺繞的……
第一問求從起點到終點所有路徑上哪些點肯定出現,其實也就是把這些點連的邊刪掉,起點就到不了終點,列舉一下,大概是O(nm)的。
第二問求有哪些個點能把圖分成兩塊,兩塊之間沒有共同的邊,只有那個分割點是公共的。我們可以發現,第二問答案的集合屬於第一問的集合,因為如果第一問的條件不滿足,第二問的條件也不會滿足。於是我們把第一問的答案每個作為分割點,每次跑兩個dfs,第一個從起點出發,跑到分割點結束;第二個從分割點出發,只要經過第一個dfs到過的點,就不是答案。應該也是O(nm)的。
#include<bits/stdc++.h> #define ll long long #define ull unsigned long long #define inf 2147483647 #define mp make_pair #define pii pair<int,int> #define pb push_back using namespace std; inline int read(){ int x=0,f=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();} while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } struct edg{ int nxt,to; }e[205]; int cnt,head[55]; int n=-1,tot,totb,a[55],b[55]; bool vis[55],vis2[55]; vector<int> gv[55]; bool f; inline void add(int u,int v){ e[++cnt].nxt=head[u],head[u]=cnt,e[cnt].to=v; } inline void dfs(int u){ if(u==n){f=1;return;} for(int i=head[u];i;i=e[i].nxt){ int v=e[i].to; if(!vis[v]) vis[v]=1,dfs(v); if(f) return; } } inline void dfs2(int u,int j){ if(u==j) return; for(int i=head[u];i;i=e[i].nxt){ int v=e[i].to; if(!vis[v]) vis[v]=1,dfs2(v,j); } } inline void dfs3(int u){ if(vis[u]){f=0;return;} for(int i=head[u];i;i=e[i].nxt){ int v=e[i].to; if(!vis2[v]) vis2[v]=1,dfs3(v); if(!f) return; } } int main() { freopen("race3.in","r",stdin); freopen("race3.out","w",stdout); while(1){ int x=read(); if(x==-1) break; ++n; while(x!=-2) gv[n].pb(x),x=read(); } for(int i=1;i<n;++i){ memset(head,0,sizeof(head));cnt=0; for(int j=0;j<n;++j){ if(i==j) continue; for(int k=0;k<(int)gv[j].size();++k){ int x=gv[j][k]; if(x==i) continue; add(j,x); } } f=0; memset(vis,0,sizeof(vis)); vis[0]=1; dfs(0); if(!f) a[++tot]=i; } printf("%d",tot); for(int i=1;i<=tot;++i) printf(" %d",a[i]); puts(""); memset(head,0,sizeof(head));cnt=0; for(int i=0;i<n;++i){ for(int k=0;k<(int)gv[i].size();++k){ int x=gv[i][k]; add(i,x); } } for(int i2=1;i2<=tot;++i2){ int i=a[i2]; memset(vis,0,sizeof(vis)); vis[0]=1; dfs2(0,i); f=1; vis[i]=0; memset(vis2,0,sizeof(vis2)); vis2[i]=1; dfs3(i); if(f) b[++totb]=i; } printf("%d",totb); for(int i=1;i<=totb;++i) printf(" %d",b[i]); puts(""); return 0; }