1. 程式人生 > >連通圖 求至少有給幾個點資訊才能傳遍全圖,至少新增幾條邊才能使全圖聯通

連通圖 求至少有給幾個點資訊才能傳遍全圖,至少新增幾條邊才能使全圖聯通

第一個,染色後求入度為0的聯通塊。

第二個,染色後求入度為0的聯通塊和出度為0的聯通塊的最大值。//入度和出度是對聯通塊說的。

AC程式碼:

#include<iostream>
#include<string>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<map>
#include<stdio.h>
#include<queue>
using namespace std;
# define maxn 200+10
# define inf 0x3f3f3f3f
# define ll long long
int num,n,ans;
int dfn[maxn];
int low[maxn];
int in[maxn];
int out[maxn];
int color[maxn];
int col;
int vis[maxn];
int Map[maxn][maxn];
map<int,int>
stack<int>q;
vector<int>wakaka[maxn];
void tarjan(int u)
{
    q.push(u);
    vis[u]=1;
    low[u]=dfn[u]=++num;
    int len=wakaka[u].size();
    for(int i=0; i<len; i++)
    {
        int v=wakaka[u][i];
        if(vis[v]==0)
        {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(vis[v ]==1)
            low[u]=min(low[u],dfn[v]);
    }
    if(low[u]==dfn[u])
    {
        int t;
        col++;
        do
        {
            t=q.top();
            q.pop();
            vis[t]=-1;
            color[t]=col;
        }
        while(u!=t);
    }
}
int main()
{
    memset(vis,0,sizeof(vis));
    memset(color,0,sizeof(color));
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(in,0,sizeof(in));
    memset(out,0,sizeof(out));
    num=col=0;
    int temp,ed;
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
    {
        while(~scanf("%d",&temp)&&temp)
        {
            wakaka[i].push_back(temp);
        }
    }
    for(int i=1; i<=n; i++)
    {
        if(vis[i]==0)
        {
            tarjan(i);
        }
    }
    if(col==1)printf("%d\n%d\n",1,0);
    else
    {
        int t1=0,t2=0;
        for(int i=1; i<=n; i++)
        {
            int t=color[i];
            int flag=0;
            int len=wakaka[i].size();
            for(int j=0; j<len; j++)
            {
                int temp=wakaka[i][j];
                if(color[temp]!=t)
                {
                    in[color[temp]]++;
                    out[t]++;
                }
            }
        }
        for(int i=1; i<=col; i++)
        {
            if(in[i]==0)t1++;
            if(out[i]==0)t2++;
        }
        printf("%d\n%d\n",t1,max(t1,t2));
    }
    return 0;

}