HDOJ 5631 Rikka with Graph

Rikka with Graph

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1079    Accepted Submission(s): 529


Problem Description
As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them:

Yuta has a non-direct graph with n vertices and n+1 edges. Rikka can choose some of the edges (at least one) and delete them from the graph.

Yuta wants to know the number of the ways to choose the edges in order to make the remaining graph connected.

It is too difficult for Rikka. Can you help her?
 

Input
The first line contains a number T(T30)——The number of the testcases.

For each testcase, the first line contains a number n(n100).

Then n+1 lines follow. Each line contains two numbers u,v , which means there is an edge between u and v.
 

Output
For each testcase, print a single number.
 

Sample Input
1 3 1 2 2 3 3 1 1 3
 

Sample Output
9


題意:給你n個點,然後n+1一條邊,問至少刪除一條邊使得圖依然聯通有多少種方案;

很明顯,對於一個圖,使得n個點聯通最小需要n-1個點,所有最多刪除兩條邊,那麼就分別暴力刪除一條邊的情況和刪除兩條邊的情況,這裏使用並查集來查詢圖的連通性,每刪除一條邊,用並查集建圖,然後查詢是否只有一個父節點,如果只有一個,那麼這個圖就是聯通的,ans++。


#include<stdio.h>
#include<algorithm>
using namespace std;
int F[200];
int n;
int a[200][2];
int findfa(int x)
{
    if(x==F[x])
        return x;
    return x=findfa(F[x]);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int ans=0;
        scanf("%d",&n);
        for(int i=1;i<=n+1;i++)
            scanf("%d%d",&a[i][0],&a[i][1]);
        for(int i=1;i<=n+1;i++)
        {
            for(int f=1;f<=n;f++)
                    F[f]=f;
            for(int j=1;j<=n+1;j++)
            {
                if(i==j)
                    continue;
                int x=a[j][0];
                int y=a[j][1];
                x=findfa(x);
                y=findfa(y);
                if(x!=y)
                    F[x]=y;
            }
            int flag=0;
            for(int j=1;j<=n;j++)
            {
                int x=findfa(j);
                if(x==j)
                    flag++;
            }
            if(flag==1)
                ans++;
        }
        for(int i=1;i<=n+1;i++)
        {
            for(int j=i+1;j<=n+1;j++)
            {
                for(int f=1;f<=n;f++)
                    F[f]=f;
                for(int k=1;k<=n+1;k++)
                {
                    if(k==i||k==j)
                        continue;
                    int x=a[k][0];
                    int y=a[k][1];
                    x=findfa(x);
                    y=findfa(y);
                    if(x!=y)
                        F[x]=y;
                }
                int flag=0;
                for(int k=1;k<=n;k++)
                {
                    int x=findfa(k);
                    if(x==k)
                        flag++;
                }
                if(flag==1)
                    ans++;
            }
        }
        printf("%d\n",ans);
    }
return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章