codeforces 732F

来源:互联网 发布:方正兰亭纤黑简体 mac 编辑:程序博客网 时间:2024/06/05 02:21
题目大意:
给一张无向图,转化为一张有向图(每条边选择一个方向),从每个点i遍历可以到达ri个点(包括自己),给出一种建图方式时得ri最小值最大。
首先如果一些点可以构成环,那么他们的连成环一定更优。
所以先求出边双,再二分答案。
其实无需二分,因为最大值一定是最大环(最大值不可能大于入度为0 的环的大小)。
当时写了二分但还是过了。
#include<cstdio>#include<cstring>#include<algorithm>#define rep(i,a,b) for(i=a;i<=b;i++)using namespace std;const int N=400010;int x[N],y[N];struct node{int to,next,pos;};node edge[N*2];int graph[N],size;int dfn[N],low[N],sig,cnt,col[N];int stack[N],top;int vis[N],flag[N];int f[N],dp[N];int n,m;int read(){int x=0;char ch=getchar();while(ch<'0'||ch>'9')ch=getchar();while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x;}void addedge(int i,int u,int v,int pos){edge[i].to=v;edge[i].pos=pos;edge[i].next=graph[u];graph[u]=i;}void tarjan(int u,int pre){int i,v;int tmp;dfn[u]=low[u]=++sig;stack[++top]=u;for(i=graph[u];i;i=edge[i].next){v=edge[i].to;if(v==pre)continue;if(!dfn[v]){tarjan(v,u);low[u]=min(low[u],low[v]);}else{low[u]=min(low[u],dfn[v]);}}if(low[u]==dfn[u]){cnt++;do{tmp=stack[top--];col[tmp]=cnt;f[cnt]++;}while(tmp!=u);}}void dfs(int u,int pre){int i,v,pos;flag[u]=1;for(i=graph[u];i;i=edge[i].next){v=edge[i].to;pos=edge[i].pos;if(vis[pos])continue;if(v==pre)continue;x[pos]=u;y[pos]=v;vis[pos]=1;if(flag[v])continue;dfs(v,u);}}inline void doit(int pos,int u,int v){if(col[x[pos]]!=u){x[pos]^=y[pos];y[pos]^=x[pos];x[pos]^=y[pos];}}void work(int u,int pre,int k){int i,v,pos,minx;dp[u]=f[u];for(i=graph[u];i;i=edge[i].next){v=edge[i].to;pos=edge[i].pos;if(v==pre)continue;work(v,u,k);if(dp[v]>=k){dp[u]+=dp[v];}}}void work1(int u,int pre,int k){int i,v,pos,minx;dp[u]=f[u];for(i=graph[u];i;i=edge[i].next){v=edge[i].to;pos=edge[i].pos;if(v==pre)continue;work1(v,u,k);if(dp[v]>=k){dp[u]+=dp[v];doit(pos,u,v);}if(dp[v]<k){doit(pos,v,u);}}}bool check(int mid){work(1,0,mid);if(dp[1]>=mid)return true;else return false;}int main(){scanf("%d%d",&n,&m);int i;rep(i,1,m){x[i]=read();y[i]=read();size++;addedge(size,x[i],y[i],i);size++;addedge(size,y[i],x[i],i);}int r1,r2;tarjan(1,0);size=0;memset(graph,0,sizeof(graph));rep(i,1,m){r1=col[x[i]];r2=col[y[i]];if(r1==r2){size++;addedge(size,x[i],y[i],i);size++;addedge(size,y[i],x[i],i);}}rep(i,1,n){if(!flag[i]){dfs(i,0);}}size=0;memset(graph,0,sizeof(graph));rep(i,1,m){r1=col[x[i]];r2=col[y[i]];if(r1!=r2){size++;addedge(size,r1,r2,i);size++;addedge(size,r2,r1,i);}}int l=0,r=n+1,mid,ans; while(l<r){mid=l+r>>1;if(check(mid)){ans=mid;l=mid+1;}else r=mid;}printf("%d\n",ans);work1(1,0,ans);rep(i,1,m){printf("%d %d\n",x[i],y[i]);}}


0 0
原创粉丝点击