标签:vector isp std 有向图 play opened eof codeforce ini
前言:关于如何求双连通分量,我们可以在tarjan搜索时标记下所有桥的位置(双连通分量(可以认为是没有桥的无向图图)即可通过删去所有桥得到),那么怎么找桥呢,对于每一条搜索到的边u->x,如果low【u】>dfn【x】则说明u不能通过子图到达比x更早的节点,那么就说明该边是桥
题意:把一个无向图变成有向图,对于这个有向图来说,每个点的价值是它所有能到达的点的数量,要求使得所有点中最小的价值最大
题解:现学的边-双联通分量,先求一遍边-双联通分量,然后在每个双连通分量里dfs一边把双向边变成单向边,最后从点数最大的那个双连通分量开始dfs,删去反向边,易证最大的点数就是答案,然后直接输出单向边即可
#include<bits/stdc++.h> #include<ext/rope> #define fi first #define se second #define mp make_pair #define pb push_back #define pii pair<int,int> #define C 0.5772156649 #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 using namespace std; using namespace __gnu_cxx; const double g=10.0,eps=1e-7; const int N=400000+10,maxn=100000+10,inf=0x3f3f3f; map<int,int>ma[N]; map<int,int>ans[N]; vector<int>v[N]; int dfn[N],low[N]; int a[N],b[N]; int index,sz; void tarjan(int u,int f) { dfn[u]=low[u]=++index; for(int i=0;i<v[u].size();i++) { int x=v[u][i]; if(x==f)continue; if(!dfn[x]) { tarjan(x,u); low[u]=min(low[u],low[x]); if(low[x]>dfn[u])ma[u][x]=ma[x][u]=1; } else low[u]=min(low[u],dfn[x]); } } void init(int n) { memset(dfn,0,sizeof dfn); memset(low,0,sizeof low); index=0; for(int i=1;i<=n;i++) { ma[i].clear(); v[i].clear(); ans[i].clear(); } } void dfs(int u,int f) { dfn[u]=1; sz++; for(int i=0;i<v[u].size();i++) { int x=v[u][i]; if(!ma[x][u]&&x!=f) { // cout<<u<<" "<<x<<endl; if(ans[x][u]&&ans[u][x])ans[x][u]=0; if(!dfn[x])dfs(x,u); } } } void dfs2(int u,int f) { dfn[u]=1; for(int i=0;i<v[u].size();i++) { int x=v[u][i]; if(!dfn[x]) { if(ans[x][u]&&ans[u][x])ans[u][x]=0; dfs2(x,u); } } } int main() { int n,m; cin>>n>>m; init(n); for(int i=0;i<m;i++) { cin>>a[i]>>b[i]; ans[a[i]][b[i]]=ans[b[i]][a[i]]=1; v[a[i]].pb(b[i]); v[b[i]].pb(a[i]); } tarjan(1,-1); memset(dfn,0,sizeof dfn); int maxx=0,id; for(int i=1;i<=n;i++) { if(!dfn[i]) { sz=0; dfs(i,-1); if(maxx<sz) { maxx=sz; id=i; } } } memset(dfn,0,sizeof dfn); dfs2(id,-1); cout<<maxx<<endl; for(int i=0;i<m;i++) { if(ans[a[i]][b[i]])cout<<a[i]<<" "<<b[i]<<endl; else cout<<b[i]<<" "<<a[i]<<endl; } return 0; } /************ 7 8 1 2 2 3 1 3 3 4 4 5 5 6 6 7 7 4 ************/
Codeforces Round #377 (Div. 2) F - Tourist Reform
标签:vector isp std 有向图 play opened eof codeforce ini
原文地址:http://www.cnblogs.com/acjiumeng/p/7744852.html