zoukankan      html  css  js  c++  java
  • CF732F Tourist Reform[边双缩点]

    题意:给无向图每一条边定向,使得每个点可达点数$R_i$最小值尽可能大,求方案。


    条件反射想到二分答案,然后看怎么检验,发现要让所有点$R_i$大于等于某一个值,首先我们关注某些特殊的子图:如果有环的话,显然可以让他定向后各点互达,并且这样的定向并不会影响其他点的$R$。进一步看,如果一个子图,定向后成了一个SCC,显然每个点都可以到达所有子图内的点,显然是很好的。而SCC对应在无向图中,是一个边双,并且因为边双可以看成是一堆环互相套和交组成的连通图,相当于每个环都定一下向,所以显然直接dfs,走过的边方向就是定下的方向,这样就是一个SCC了,可以画图感性理解。。。然后就直接跑边双就行了,缩点之后,成了一棵树,然后树边都是桥,定向的话最后肯定会有至少一个点没有出度,也就是他没有可以走到的点了,那么不妨直接以最大的这个点为无出度点,看他有没有超过mid,再然后发现并不需要二分答案,所以就直接求了。

    上述思路有点乱,因为我这题很迷,昨晚没翻题解切掉了,结果今天不会做了。。所以上面这段文字是我今日口胡。。。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<queue>
     7 #define mst(x) memset(x,0,sizeof x)
     8 #define dbg(x) cerr << #x << " = " << x <<endl
     9 #define dbg2(x,y) cerr<< #x <<" = "<< x <<"  "<< #y <<" = "<< y <<endl
    10 using namespace std;
    11 typedef long long ll;
    12 typedef double db;
    13 typedef pair<int,int> pii;
    14 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
    15 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
    16 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;}
    17 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;}
    18 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
    19 template<typename T>inline T read(T&x){
    20     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
    21     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
    22 }
    23 const int N=4e5+7;
    24 struct thxorz{
    25     int to[N<<1],head[N],nxt[N<<1],tot;
    26     thxorz(){tot=1;}
    27     inline void add(int x,int y){
    28         to[++tot]=y,nxt[tot]=head[x],head[x]=tot;
    29         to[++tot]=x,nxt[tot]=head[y],head[y]=tot;
    30     }
    31 }G1,G2;
    32 struct stothx{
    33     int u,v,d;
    34     stothx(int u=0,int v=0,int d=-1):u(u),v(v),d(d){}
    35 }e[N];
    36 int id[N<<1];
    37 int n,m,dcc;
    38 #define y G1.to[j]
    39 int dfn[N],low[N],tim,cut[N<<1],bel[N],sum[N];
    40 void tarjan(int x,int l){
    41     dfn[x]=low[x]=++tim;
    42     for(register int j=G1.head[x];j;j=G1.nxt[j])if(j^(l^1)){
    43         if(!dfn[y]){
    44             tarjan(y,j);MIN(low[x],low[y]);
    45             if(low[y]>dfn[x])cut[j]=cut[j^1]=1;
    46         }
    47         else MIN(low[x],dfn[y]);
    48     }
    49 }
    50 void dfs(int x){
    51     bel[x]=dcc;++sum[dcc];//dbg2(x,dcc);
    52     for(register int j=G1.head[x];j;j=G1.nxt[j])if(!cut[j]){
    53         if(e[j>>1].d==-1)x^e[j>>1].u?e[j>>1].d=1:e[j>>1].d=0;
    54         if(!bel[y])dfs(y);
    55     }
    56 }
    57 #undef y
    58 #define y G2.to[j]
    59 void dfs2(int x,int fa){
    60     for(register int j=G2.head[x];j;j=G2.nxt[j])if(y^fa)dfs2(y,x),bel[e[id[j]].u]^x?e[id[j]].d=0:e[id[j]].d=1;
    61 }
    62 #undef y
    63 int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
    64     read(n),read(m);
    65     for(register int i=1,x,y;i<=m;++i){
    66         read(x),read(y);
    67         G1.add(x,y);
    68         e[i].u=x,e[i].v=y;
    69     }
    70     for(register int i=1;i<=n;++i)if(!dfn[i])tarjan(i,0);
    71     for(register int i=1;i<=n;++i)if(!bel[i])++dcc,dfs(i);
    72     for(register int i=1,x,y;i<=m;++i){//m --- n   -_-
    73         x=e[i].u,y=e[i].v;//dbg2(x,y),dbg2(bel[x],bel[y]);
    74         if(bel[x]^bel[y])G2.add(bel[x],bel[y]),id[G2.tot]=id[G2.tot-1]=i;
    75     }
    76     int tmp=0,rt;
    77     for(register int i=1;i<=dcc;++i)if(MAX(tmp,sum[i]))rt=i;dbg2(tmp,rt);
    78     dfs2(rt,0);
    79     printf("%d
    ",tmp);
    80     for(register int i=1;i<=m;++i)e[i].d?printf("%d %d
    ",e[i].v,e[i].u):printf("%d %d
    ",e[i].u,e[i].v);
    81     return 0;
    82 }
    View Code

    总结:总结啥啊。。

  • 相关阅读:
    segmentation fault(core dumped)
    (LIS LCS 例题)Max Sum Advanced Fruits Super Jumping! Jumping! Jumping!
    几种数学公式(环排列 母函数 唯一分解定理 卡特兰数 默慈金数 贝尔数 那罗延数)
    map set 详解
    算法录 之 二分和三分
    LIS 最长上升子序列 LCS 最长公共子序列 模板
    JAVA 大数据 例题
    Java 实现大数算法
    7 21 第一次团队赛——————写给队友
    离散化+unique()+二分查找
  • 原文地址:https://www.cnblogs.com/saigyouji-yuyuko/p/11727454.html
Copyright © 2011-2022 走看看