您的位置:首页 > 其它

CodeForces 732F Tourist Reform

2017-02-08 17:12 393 查看
边双连通分量。

这题有一点构造的味道。一个有向图,经过强连通缩点之后会形成一个有向无环图。

如果将最大的强连通分量放在顶端,其余的强连通分量都直接或间接指向他,那么这样就构造出了符合要求的图。

接下来就是要去寻找强连通分量。对于一个无向图来说,每一个边-双联通分量都可以将每条边定向之后构造成一个强连通分量,$dfs$一遍即可。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<ctime>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-10;
void File()
{
freopen("D:\\in.txt","r",stdin);
freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
char c = getchar();
x = 0;
while(!isdigit(c)) c = getchar();
while(isdigit(c))
{
x = x * 10 + c - '0';
c = getchar();
}
}

const int maxn = 800000 + 5;
int n,m;

int pre[maxn], dfs_clock, bcc_cnt;
vector<int>G[maxn], bcc[maxn];

int belong[maxn],U[maxn],V[maxn],sz;
int flag[maxn],ff[maxn],gg[maxn],ge[maxn],dd[maxn];

int Tarjan(int u,int fa)
{
int lowu=pre[u]=++dfs_clock;

for(int i=0;i<G[u].size();i++)
{
int v=V[G[u][i]];
if(!pre[v])
{
int lowv=Tarjan(v,u);
lowu=min(lowu,lowv);

if(lowv > pre[u]) ge[(G[u][i]+1)/2]=1;
}
else if(v!=fa) lowu=min(lowu,pre[v]);
}

return lowu;
}

void add(int a,int b)
{
sz++; U[sz]=a; V[sz]=b;
G[a].push_back(sz);
}

void DFS(int x,int y)
{
flag[y]=1;
for(int i=0;i<G[y].size();i++)
{
int v=V[G[y][i]];
if(v==x) continue;
if(ff[(G[y][i]+1)/2]==1) continue;
ff[(G[y][i]+1)/2]=1;
gg[G[y][i]]=1;
if(flag[v]==0) DFS(y,v);
}
}

void dfs(int x)
{
belong[x]=bcc_cnt;
for(int i=0;i<G[x].size();i++)
{
if(ge[(G[x][i]+1)/2]==1) continue;
int v=V[G[x][i]];
if(belong[v]!=0) continue;
dfs(v);
}
}

int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int a,b; scanf("%d%d",&a,&b);
add(a,b); add(b,a);
}

for (int i = 1; i <= n; i++) if (!pre[i]) Tarjan(i, -1);

for(int i=1;i<=n;i++)
{
if(belong[i]!=0) continue;
bcc_cnt++; dfs(i);
}

for(int i=1;i<=n;i++) dd[belong[i]]++;

int mx=0,idx=0;
for(int i=1;i<=bcc_cnt;i++) if(dd[i]>mx) mx=dd[i],idx=i;

for(int i=1;i<=n;i++) if(belong[i]==idx) { DFS(-1,i); break; }

printf("%d\n",mx);
for(int i=1;i<=sz;i++)
if(gg[i]) printf("%d %d\n",V[i],U[i]);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: