HDU 2767-Proving Equivalences(强联通+缩点)

题目地址:HDU 2767

题意:给一张有向图,求最少加几条边使这个图强连通。

思路:先求这张图的强连通分量,如果为1,则输出0(证明该图不需要加边已经是强连通的了),否则缩点。遍历原图的所有边,如果2个点在不同的强连通分量里面,建边,构成一张新图。统计新图中点的入度和出度,取入度等于0和出度等于0的最大值(因为求强连通缩点后,整张图就变成了一个无回路的有向图,要使之强连通,只需要将入度=0和出度=0的点加边即可,要保证加边后没有入度和出度为0的点,所以取两者最大值)

*#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <set>
#include <queue>
#include <stack>
#include <map>
using namespace std;
typedef long long LL;
const int inf=0x3f3f3f3f;
const double pi= acos(-1.0);
const double esp=1e-6;
const int maxn=21010;
int head[maxn],dfn[maxn],low[maxn],belong[maxn],stak[maxn],instack[maxn];
int in[maxn],out[maxn];
int incnt,outcnt;
int cnt,index,top,ans;
struct node {
    int u, v, next;
} edge[maxn*3];
void add(int u, int v) {
    edge[cnt].v=v;
    edge[cnt].next=head[u];
    head[u]=cnt++;
}
void Init() {
    memset(head,-1,sizeof(head));
    memset(dfn,0,sizeof(dfn));
    memset(instack,0,sizeof(instack));
    cnt=index=top=ans=0;
    memset(in,0,sizeof(in));
    memset(out,0,sizeof(out));
    incnt=outcnt=0;
}
void tarjan(int u) {
    dfn[u]=low[u]=++index;
    stak[++top]=u;
    instack[u]=1;
    for(int i=head[u]; i!=-1; i=edge[i].next) {
        int v=edge[i].v;
        if(!dfn[v]) {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        } else if(instack[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]) {
        ans++;
        while(1) {
            int v=stak[top--];
            instack[v]=0;
            belong[v]=ans;
            if(u==v) break;
        }
    }
}
int main() {
    int T, n, m,i, j;
    int u,v;
    scanf("%d",&T);
    while(T--) {
        scanf("%d%d",&n,&m);
        Init();
        while(m--) {
            scanf("%d%d",&u,&v);
            add(u,v);
        }
        for(i=1; i<=n; i++) {
            if(!dfn[i])
                tarjan(i);
        }
        if(ans==1) {
            printf("0\n");
            continue ;
        }
        for(i=1; i<=n; i++) {
            for(j=head[i]; j!=-1; j=edge[j].next) {
                int v=edge[j].v;
                if(belong[v]!=belong[i]) {
                    in[belong[v]]++;
                    out[belong[i]]++;
                }
            }
        }
        for(i=1; i<=ans; i++) {
            if(!in[i])
                incnt++;
            if(!out[i])
                outcnt++;
        }
        printf("%d\n",max(incnt,outcnt));
    }
    return 0;
}*

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

时间: 2024-11-05 13:35:30

HDU 2767-Proving Equivalences(强联通+缩点)的相关文章

HDU 2767 Proving Equivalences(强联通缩点)

Proving 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

HDU 2767 Proving Equivalences (强联通)

http://acm.hdu.edu.cn/showproblem.php?pid=2767 Proving Equivalences Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2926    Accepted Submission(s): 1100 Problem Description Consider the followi

HDU 2767 Proving Equivalences 图论scc缩点

问一个图,最少需要加多少条边,使得这个图强联通. Tarjan缩点,重建图,令a=入度为0的scc个数,b=出度为0的scc个数,ans=max(a,b): 若图scc=1,本身强联通,ans=0: 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MAXN = 20010;//点数 4 const int MAXM = 200100;//边数 5 struct Edge { 6 int to,next; 7 }edge[

hdu 2767 Proving Equivalences 强连通缩点

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

HDU 2767 Proving Equivalences(强连通 Tarjan+缩点)

HDU 2767 Proving Equivalences(强连通 Tarjan+缩点) ACM 题目地址:HDU 2767 题意: 给定一张有向图,问最少添加几条边使得有向图成为一个强连通图. 分析: Tarjan入门经典题,用tarjan缩点,然后就变成一个有向无环图(DAG)了. 我们要考虑的问题是让它变成强连通,让DAG变成强连通就是把尾和头连起来,也就是入度和出度为0的点. 统计DAG入度和出度,然后计算头尾,最大的那个就是所求. 代码: /* * Author: illuz <iil

hdu 2767 Proving Equivalences(强连通入门题)

1 /************************************************* 2 Proving Equivalences(hdu 2767) 3 强连通入门题 4 给个有向图,求至少加多少条边使得图是所有点都是强连通的 5 由a->b->c->a易知n个点至少要n条边,每个出度和入度都要大 6 于1.先求所有所有强连通分量,把每个强连通分量看成一个点 7 在找每个点的出度和入度,最后还差的出度和入度的最大值就是 8 答案. 9 10 ************

HDU 2767 Proving Equivalences

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

HDU 2767 Proving Equivalences (Tarjan縮點)

Time limit :2000 ms Memory limit :32768 kB 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 soluti

POJ 1236 Network of School(强联通缩点)

Description A number of schools are connected to a computer network. Agreements have been developed among those schools: each school maintains a list of schools to which it distributes software (the "receiving schools"). Note that if B is in the