Rikka with Graph
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1233 Accepted Submission(s): 639
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?
For each testcase, the first line contains a number n(n≤100).
Then n+1 lines follow. Each line contains two numbers u,v , which means there is an edge between u and v.
#include <stdio.h>
#include <string.h>
const int maxn = 1e2 + 10;
int par[maxn];
struct node //把邊用結構體存下來,每個結構體對應一條邊;
{
int st;
int edd;
}edge[maxn];
void init(int n)
{
for (int i = 0; i <= n; i++)
par[i] = i;
}
int find(int x)
{
return par[x] == x ? x : par[x] = find(par[x]);
}
void unite(int a, int b)
{
int fa = find(a);
int fb = find(b);
if (fa != fb)
par[fa] = fb;
}
bool check(int n) //統計是不是隻有一個根節點,即使不是能全部連通
{
int sum = 0;
for (int i = 1; i <= n; i++)
if (par[i] == i)
sum++;
return sum == 1;
}
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
int n;
scanf("%d", &n);
for (int i = 0; i < n + 1; i++)
scanf("%d%d", &edge[i].st, &edge[i].edd);
int sum = 0; //sum記錄可行的個數
//題上說總共給出n + 1條邊 然後我們已知n個點至少需要n - 1條邊連接 數據是100左右 n^3也可以過 那就暴力枚舉
//先枚舉去掉一條邊是否能連通
for (int i = 0; i < n + 1; i++)
{
init(n); //這一步記得 因爲是枚舉 每次枚舉出來一條邊 這個數組就要重新排列一下 回覆初始狀態
for (int j = 0; j < n + 1; j++)
{
if (i == j) //上面用i記錄去掉的邊 那麼這一步就沒有這條邊了 所以遇到相等就跳過
continue;
unite(edge[j].st, edge[j].edd); //把剩下的每個邊都連接起來
}
//然後在這做檢查 看能不能連通所有的點
if (check(n))
sum++;
}
//枚舉一條邊的就結束了 下面的兩條邊的和一條邊的幾乎相同
for (int i = 0; i < n + 1; i++)
{
for (int j = i + 1; j < n + 1; j++)
{
init(n);
for (int k = 0; k < n + 1; k++)
{
if (k == i || k == j)
continue;
unite(edge[k].st, edge[k].edd);
}
if (check(n))
sum++;
}
}
printf("%d\n", sum);
}
return 0;
}