HDU2767Proving Equivalences(强连通+缩点+ 至少加几条边让整个图变成强连通))

题意: 至少加几条边让整个图变成强连通。

思路:对于N个点的图,我们知道至少需要N条边才能使这个图强连通,现在我们先对题目的图计算一下强连通,对于已经在一个强连通的点,把他们看做为一个点,然后对新形成的图,计算出度,入度为0的最大值,因为,加一边,可以使入度,出度加一。


#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<string>
#include<cstring>
#include<stack>
#include<queue>
#include<vector>
#include<cstdlib>
#define lson (rt<<1),L,M
#define rson (rt<<1|1),M+1,R
#define M ((L+R)>>1)
#define cl(a,b) memset(a,b,sizeof(a));
#define LL long long
#define P pair<int,int>
#define X first
#define Y second
#define pb push_back
#define fread(zcc)  freopen(zcc,"r",stdin)
#define fwrite(zcc) freopen(zcc,"w",stdout)
using namespace std;
const int maxn=30005;
const int inf=999999;

vector<int> G[maxn];
int low[maxn],dfn[maxn],belong[maxn],s[maxn];
bool ins[maxn];
int cnt,num,top;

void dfs(int u){
    dfn[u]=low[u]=++num;
    s[++top]=u;
    ins[u]=true;
    int N=G[u].size();
    for(int i=0;i<N;i++){
        int v=G[u][i];
        if(!dfn[v]){
            dfs(v);
            low[u]=min(low[u],low[v]);
        }
        else if(ins[v]&&dfn[v]<low[u]){
            low[u]=dfn[v];
        }
    }
    if(dfn[u]==low[u]){
        int v;
        cnt++;
        do{
            v=s[top--];
            ins[v]=false;
            belong[v]=cnt;
        }while(u!=v);
    }
}
void Tarjan(int n){
    cnt=num=top=0;
    cl(belong,0);
    cl(ins,false);
    cl(dfn,0);
    for(int i=1;i<=n;i++){
        if(!dfn[i])dfs(i);
    }
}

int in[maxn],out[maxn];
int main(){
    int T;
    int n,m;
    scanf("%d",&T);
    while(T--){
        int n,m;
        scanf("%d%d",&n,&m);
        if(m==0){
            printf("%d\n",n);continue;
        }
        for(int i=0;i<=n;i++)G[i].clear();
        for(int i=0;i<m;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            G[x].pb(y);
        }

        Tarjan(n);
        if(cnt<=1){//特判
            printf("0\n");continue;
        }
        cl(in,0);
        cl(out,0);
        for(int i=1;i<=n;i++){//进行缩点,在一个强连通的中的点,看为一个
            for(int j=0;j<G[i].size();j++){
                if(belong[i]!=belong[G[i][j]]){
                    in[belong[G[i][j]]]++;
                    out[belong[i]]++;
                }
            }
        }
        int xx=0,yy=0;
        for(int i=1;i<=cnt;i++){
            if(!in[i])xx++;
            if(!out[i])yy++;
        }
        printf("%d\n",max(xx,yy));
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-05 12:08:32

HDU2767Proving Equivalences(强连通+缩点+ 至少加几条边让整个图变成强连通))的相关文章

POJ 1236--Network of Schools【scc缩点构图 &amp;&amp; 求scc入度为0的个数 &amp;&amp; 求最少加几条边使图变成强联通】

Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 13325   Accepted: 5328 Description A number of schools are connected to a computer network. Agreements have been developed among those schools: each school maintains a li

poj 3352 Road Construction【边双连通求最少加多少条边使图双连通&amp;&amp;缩点】

Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10141   Accepted: 5031 Description It's almost summer time, and that means that it's almost summer construction time! This year, the good people who are in charge of the r

hdu 2767 强连通缩点处理加边问题

#include <cstring> #include <cstdlib> #include <cstdio> 缩点的好处就是可以将乱七八糟的有向图 转化为无环的有向图#include <iostream> #include <algorithm> #include <cmath> #include <stack> using namespace std; #define MAXN 200010 #define clr(x

HDU2767Proving Equivalences[tarjan 缩点]

Proving Equivalences Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6006    Accepted Submission(s): 2051 Problem Description Consider the following exercise, found in a generic linear algebra t

hdu3861The King’s Problem (强连通 缩点+最小路径覆盖)

The King's Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1606 Accepted Submission(s): 584 Problem Description In the Kingdom of Silence, the king has a new problem. There are N cities in

hdu2767Proving Equivalences(强连通,缩点)

Problem Description Consider the following exercise, found in a generic linear algebra textbook. Let A be an n × n matrix. Prove that the following statements are equivalent: 1. A is invertible. 2. Ax = b has exactly one solution for every n × 1 matr

hdu 2767 Proving Equivalences 强连通缩点

给出n个命题,m个推导,问最少增加多少条推导,可以使所有命题都能等价(两两都能互推) 既给出有向图,最少加多少边,使得原图变成强连通. 首先强连通缩点,对于新图,每个点都至少要有一条出去的边和一条进来的边(这样才能保证它能到任意点和任意点都能到它) 所以求出新图中入度为0的个数,和出度为0的个数,添加的边就是从出度为0的指向入度为0的.这样还会有一点剩余,剩余的就乱连就行了. 所以只要求出2者的最大值就OK. #include <iostream> #include<cstring>

UVA-11324 The Largest Clique 【有向图强连通+缩点+DP】

题目链接:https://vjudge.net/problem/UVA-11324 题目大意:给定一张有向图G,求一个结点数最大的结点集,集合中每两个点都至少有一条路径相连(方向任意). 题解: 易知如果一个点被选择,则它所在强连通分量中的其他点也一定要选,如果不选,则其他点也不可选,因此先求出强连通分量,利用缩点创建出另一张有向图G2,每个结点的权值就是该强连通分量的结点数,再DP求解. 代码: 1 #include<bits/stdc++.h> 2 using namespace std;

Light OJ 1168 Wishing Snake 强连通缩点+哈密顿通路

题目来源:Light OJ 1168 Wishing Snake 题意:有点难看懂题意 看了一个小时再加别人的代码才懂意思 从0开始 输入的那些每一对u v 都要经过 就是从0到到达那些点 思路:首先缩点 每一个强连通分量里面的点都是可达的 缩点后的图是有向无环图 如果从0这个强连通分量可以出去到2个强连通分量 那么这两个强连通分量是不可能相互可达 所以可行的方案就是所有的强连通分量连成一线 一个一个串起来 除了第一个 出度是1入度是0和最后一个出度是0入度是1 其他都是入度等于出度是1 特判只