HDU 2767-Proving Equivalences(強聯通+縮點)
阿新 • • 發佈:2018-03-02
ble include string blog 題意 sca def size out
題目地址:
pid=2767">HDU 2767
題意:給一張有向圖。求最少加幾條邊使這個圖強連通。
思路:先求這張圖的強連通分量。假設為1。則輸出0(證明該圖不須要加邊已經是強連通的了)。否則縮點。
遍歷原圖的全部邊。假設2個點在不同的強連通分量裏面,建邊,構成一張新圖。統計新圖中點的入度和出度,取入度等於0和出度等於0的最大值(由於求強連通縮點後。整張圖就變成了一個無回路的有向圖。要使之強連通。僅僅須要將入度=0和出度=0的點加邊就可以,要保證加邊後沒有入度和出度為0的點,所以取兩者最大值)
PS:補充一下縮點的含義:我們求強連通分量時,給每一個頂點做一個標記,標記該頂點屬於哪個強聯通分量,然後屬於同一個強連通分量的點就能夠看作同一個點了。
這就是所謂的“縮點”
*#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;
}*
HDU 2767-Proving Equivalences(強聯通+縮點)