CodeForces 732F Tourist Reform

边双连通分量。

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

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

接下来就是要去寻找强连通分量。对于一个无向图来说,每一个边-双联通分量都可以将每条边定向之后构造成一个强连通分量,$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;
}
时间: 2024-08-26 01:08:09

CodeForces 732F Tourist Reform的相关文章

CF 732F Tourist Reform——v-SCC+dfs

题目:http://codeforces.com/contest/732/problem/F 给无向图定向使得从每个点出发能去的点数最小值最大. SCC.点内部dfs定向.点间以siz最大的为起点反向dfs. 自我感觉良好的自己写法:在新连边的时候只是操作一下 thd 和 tnxt 即可. 注意写了构造函数的话结构体成员的初值就不是自动赋值为0了. #include<iostream> #include<cstdio> #include<cstring> using n

codeforces CF732F Tourist Reform Tarjan边双连通分量

$ \rightarrow $ 戳我进CF原题 一张有向图中,设 $ r_i $ 为从点 $ i $ 出发能够到达的点的数量. 定义有向图的"改良值"为 $ r_i $ 的最小值. 现给出一张无向图,要求给每条边定一个方向,使产生的有向图"改良值"最大. $ n,m \le 400000 $ 对于无向图的每个"边双连通分量",一定存在一种定向方法,使其改良值等于其大小 把无向图缩点后,以最大的 $ e-DCC $ 为零出度点(终点) $ BFS

Codeforces 538C. Tourist&#39;s Notes

A tourist hiked along the mountain range. The hike lasted for n days, during each day the tourist noted height above the sea level. On the i-th day height was equal to some integer hi. The tourist pick smooth enough route for his hike, meaning that t

[2016-04-01][codeforces][659E][New Reform]

时间:2016-04-01 19:27:59 星期五 题目编号:[2016-04-01][codeforces][659E][New Reform] 题目大意:给定n个城市,m条路,每条路连接两个城市,每两个城市最多只有一条路连接,现在把路改成单项的,问最少会出现几个孤立的城市(没有城市到达它), 分析: 在一个联通分支中,如果边数为n - 1,那么这个图就是树,树上除了根节点,其他节点都可达,如果边数大于n-1,那么至少会出现一个环,只要选的点在环上,那么所有的点都可达 题目不止一个联通分支,

CodeForces 659E New Reform

题意:给你一个无向图,如今要求你把边改成有向的. 使得入度为0的点最少,输出有多少个点入度为0 思路:脑补一波结论.假设有环的话显然没有点入度为0,其余则至少有一个点入度为0,然后就DFS一波就能够了 #include <cstdio> #include <queue> #include <cstring> #include <iostream> #include <cstdlib> #include <algorithm> #inc

codeforces 340C Tourist Problem(公式题)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Tourist Problem Iahub is a big fan of tourists. He wants to become a tourist himself, so he planned a trip. There are n destinations on a straight road that Iahub wants to visit. Iahub starts

CodeForces 659E New Reform (图的遍历判环)

Description Berland has n cities connected by m bidirectional roads. No road connects a city to itself, and each pair of cities is connected by no more than one road. It isnot guaranteed that you can get from any city to any other one, using only the

CF732 F Tourist Reform——边双连通分量

题目:http://codeforces.com/contest/732/problem/F 首先把边双缩点,边双内部 dfs 一个顺序一定是可以从每个点走到边双内部所有点的,因为它是以环为基本单位: 然后对于缩点之后的图,找到 siz 最大的点作为根 dfs,再连反边,那么只有 siz 最大的那个点只能走到自己内部,就可以使答案最大: 结构体要开得精细一点,防止爆空间?还是什么奇奇怪怪的错误之类的... 代码如下: #include<iostream> #include<cstdio&

CodeForces 723E One-Way Reform

构造. 有一种十分巧妙的方法可以使图中所有度数为偶数的节点,经过每条边定向后,出度和入度都相等. 首先统计每个节点的度数,将度数为奇数的节点与编号为$n+1$的节点连边,这样一来,这张新图变成了每个节点的度数都是偶数的图,必然存在欧拉回路.任意一条欧拉回路都使得原图中度数为偶数的节点的出度与入度相等. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cs