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[MAXM];
 8 int head[MAXN],tot,a,b;
 9 int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN];//Belong数组的值是1~scc
10 int Index,top; int scc;//强连通分量的个数
11 int in[MAXN],out[MAXN];
12 bool Instack[MAXN];
13 int num[MAXN];//各个强连通分量包含点的个数,数组编号1~scc //num数组不一定需要,结合实际情况
14
15 void addedge(int u,int v){
16     edge[tot].to = v;
17     edge[tot].next = head[u];
18     head[u] = tot++;
19 }
20 void Tarjan(int u){
21     int v;
22     Low[u] = DFN[u] = ++Index;
23     Stack[top++] = u;
24     Instack[u] = true;
25     for(int i = head[u];i != -1;i = edge[i].next) {
26         v = edge[i].to;
27         if( !DFN[v] ){
28             Tarjan(v);
29             if( Low[u] > Low[v] )
30                 Low[u] = Low[v];
31         }
32         else if(Instack[v] && Low[u] > DFN[v])
33             Low[u] = DFN[v];
34         }
35         if(Low[u] == DFN[u]){
36             scc++;
37             do{
38                 v = Stack[--top];
39                 Instack[v] = false;
40                 Belong[v] = scc;
41                 num[scc]++;
42             }while( v != u);
43         }
44 }
45 void find_degree(int u){
46     int v;
47     for(int i = head[u];i != -1;i = edge[i].next){
48         v = edge[i].to;
49         if(Belong[u]==Belong[v]) continue;
50         in[Belong[v]]++;
51         out[Belong[u]]++;
52     }
53 }
54 void solve(int N){
55     memset(DFN,0,sizeof(DFN));
56     memset(Instack,false,sizeof(Instack));
57     memset(num,0,sizeof(num));
58     Index = scc = top = 0;
59     for(int i = 1;i <= N;i++)
60         if(!DFN[i])
61         Tarjan(i);
62     for(int i=1;i<=N;i++){
63         find_degree(i);
64     }
65     if(scc==1) return;
66     for(int i=1;i<=scc;i++){
67         if(in[i]==0) a++;
68         if(out[i]==0) b++;
69     }
70 }
71 void init(){
72     tot = 0;
73     a=0,b=0;
74     memset(head,-1,sizeof(head));
75     memset(in,0,sizeof(in));
76     memset(out,0,sizeof(out));
77 }
78 int main(){
79     int n,m,u,v,T;
80     cin>>T;
81     while(T--){
82         scanf("%d%d",&n,&m);
83         init();
84         for(int i=1;i<=m;i++){
85             scanf("%d%d",&u,&v);
86             addedge(u,v);
87         }
88         solve(n);
89         cout<<max(a,b)<<endl;
90     }
91     return 0;
92 }
时间: 2024-10-11 22:05:43

HDU 2767 Proving Equivalences 图论scc缩点的相关文章

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(强连通 Tarjan+缩点)

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

hdu 2767 Proving Equivalences 强连通缩点

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

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(强连通入门题)

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

hdoj 2767 Proving Equivalences【求scc&amp;&amp;缩点】【求最少添加多少条边使这个图成为一个scc】

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

HDU 2767--Proving Equivalences【scc缩点构图 &amp;&amp; 求向图中最少增加多少条边才可以使新图强连通】

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