1. 程式人生 > >CF732F Tourist Reform(邊雙聯通)

CF732F Tourist Reform(邊雙聯通)

code num str ont open scanf mes urn ==

題意

在一張有向圖中,設 ri 為從點 i 出發能夠到達的點的數量。

定義有向圖的“改良值”為 ri 的最小值。

現給出一張無向圖,要求給每條邊定一個方向,使產生的有向圖“改良值”最大。

輸出 最大改良值和邊的方向。

n,m≤400000

題解

對於無向圖的每個“邊雙連通分量”,一定存在一種定向方法,使其改良值等於其大小

把無向圖縮點後,以最大的 e-DCC 為零出度點(終點) BFS 定向

每個 e-DCC 內部 DFS 定向

技術分享圖片
  1 #include<iostream>
  2 #include<cstring>
  3 #include<algorithm>
  4
#include<cmath> 5 #include<cstdio> 6 #include<queue> 7 using namespace std; 8 int const N=400100; 9 int head[N],cnt; 10 int dfn[N],low[N],tot,flag[N*2]; 11 int c[N],t[N]; 12 int vis[N]; 13 int n,m,u[N],v[N],w[N],num; 14 struct edge{ 15 int to,nxt,flag; 16 }e[N*3];
17 void add(int u,int v){ 18 cnt++; 19 e[cnt].nxt=head[u]; 20 e[cnt].to=v; 21 head[u]=cnt; 22 } 23 void Tarjan(int u,int from){ 24 dfn[u]=low[u]=++tot; 25 for(int i=head[u];i;i=e[i].nxt){ 26 int v=e[i].to; 27 if(!dfn[v]){ 28 Tarjan(v,i);
29 if(e[i].flag==0&&e[i^1].flag==0)e[i].flag=1; 30 low[u]=min(low[u],low[v]); 31 if(dfn[u]<low[v]){ 32 flag[i]=flag[i^1]=1; 33 e[i].flag=e[i^1].flag=0; 34 } 35 } 36 else if(i!=(from^1)){ 37 if(e[i].flag==0&&e[i^1].flag==0)e[i].flag=1; 38 low[u]=min(low[u],dfn[v]); 39 } 40 } 41 } 42 void bfs(int u,int col){ 43 queue<int> q; 44 q.push(u); 45 c[u]=col; 46 t[col]=1; 47 while(!q.empty()){ 48 int u=q.front(); 49 q.pop(); 50 for(int i=head[u];i;i=e[i].nxt){ 51 int v=e[i].to; 52 if(c[v]||flag[i])continue; 53 c[v]=col; 54 t[col]++; 55 q.push(v); 56 } 57 } 58 } 59 void dfs(int u){ 60 vis[u]=1; 61 for(int i=head[u];i;i=e[i].nxt){ 62 int v=e[i].to; 63 if(vis[v]==0){ 64 if(c[u]!=c[v])e[i].flag=1; 65 dfs(v); 66 } 67 } 68 } 69 int main(){ 70 scanf("%d%d",&n,&m); 71 cnt=1; 72 for(int i=1;i<=m;i++){ 73 scanf("%d%d",&u[i],&v[i]); 74 add(u[i],v[i]); 75 add(v[i],u[i]); 76 } 77 Tarjan(1,0); 78 int maxx=0,s; 79 for(int i=1;i<=n;i++){ 80 if(!c[i])bfs(i,++num); 81 if(t[num]>maxx){ 82 maxx=t[num]; 83 s=num; 84 } 85 } 86 printf("%d\n",maxx); 87 for(int i=1;i<=n;i++){ 88 if(c[u[i]]==c[v[i]])continue; 89 } 90 for(int i=1;i<=n;i++){ 91 if(!vis[i]&&c[i]==s){ 92 dfs(i); 93 break; 94 } 95 } 96 for(int i=2;i<=cnt;i+=2){ 97 if(e[i].flag==0)printf("%d %d\n",u[i/2],v[i/2]); 98 else printf("%d %d\n",v[i/2],u[i/2]); 99 } 100 return 0; 101 }
View Code

CF732F Tourist Reform(邊雙聯通)