生活随笔
收集整理的這篇文章主要介紹了
poj1236-Tarjan算法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目大意:
一些學校連成了網絡, 在學校之間存在某個協議:每個學校都維護一張傳送表,表明他們要負責將收到的軟件傳送到表中的所有學校。如果A在B的表中,那么B不一定在A的表中。
現在的任務就是,給出所有學校及他們維護的表,問1、如果所有學校都要被傳送到,那么需要幾份軟件備份;2、如果只用一份軟件備份,那么需要添加幾條邊?
題解:
1.即求強聯通分量的個數,或者說是縮點以后入度為0的個數。
2.所有學校都連成一個強聯通分量,只需要將圖中的強聯通分量互相之間聯通就好了。添加的邊數就是縮點后入度為0的點和出度為0的點的最大值。
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
#define MAXN 110
#define INF 0x3f3f3f3f
int n;
int map[MAXN][MAXN];
int low[MAXN];
int dfn[MAXN];
int stack[MAXN], head;
int instack[MAXN];
int belong[MAXN];
int in[MAXN];
int out[MAXN];
int index, cnt;
int min(
int a,
int b)
{
return a < b ? a : b;
}
int max(
int a,
int b)
{
return a > b ? a : b;
}
void init()
{
int i, j;
int temp;
memset(
map,
0,
sizeof(
map));
memset(dfn, -
1,
sizeof(dfn));
memset(low,
0,
sizeof(low));
memset(instack,
0,
sizeof(instack));index = cnt =
1;head =
0;
for(i=
1; i <= n; i++){
while(
scanf(
"%d", &temp) && temp){
map[i][temp] =
1;}}
}
void tarjan(
int x)
{
int i, a;low[x] = dfn[x] = index; index++;
stack[++head] = x; instack[x] =
1;
for(i =
1; i <= n; i++) {
if(!
map[x][i])
continue;
if(dfn[i] == -
1) {tarjan(i); low[x] = min(low[x], low[i]); }
else if(instack[i]) {low[x] = min(low[x], dfn[i]); } }
if(low[x] == dfn[x]) {
int temp;
while(
1) {temp =
stack[head--]; belong[temp] = cnt; instack[temp] =
0;
if(temp == x)
break;}cnt++;}
}
void solve()
{
int i, j;
int t1, t2;
while(
scanf(
"%d", &n) != EOF) {init();
for(i =
1; i <= n; i++)
if(dfn[i] == -
1) tarjan(i); **
for(i =
1; i <= n; i++) {
for(j =
1;j <= n; j++){
if(
map[i][j] && belong[i] != belong[j]) {out[belong[i]]++; in[belong[j]]++;} } }** t1 =
0, t2 =
0;
for(i =
1; i < cnt; i++){
if(in[i] ==
0)t1++;
if(out[i] ==
0)t2++;}
if(cnt ==
2)
printf(
"1\n0\n");
elseprintf(
"%d\n%d\n", t1, max(t1, t2));}
}
int main()
{
#ifdef LOCALfreopen(
"poj1236.txt",
"r", stdin);
#endifsolve();
return 0;
}
轉載于:https://www.cnblogs.com/luckycode/p/5255650.html
總結
以上是生活随笔為你收集整理的poj1236-Tarjan算法的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。