题目描述
Acmar and Ibmar are at war! You are in charge of a rail network that transports important supplies throughout the great state of Acmar during this delicate time. The rail system is made up of a set of rail lines which meet at various junction points. While there is no limit to the number of rail lines that can meet at a junction, the network is set up so that there is only one path between any two junctions. You’ve tried to argue for some redundancy in the system, i.e., extra rail lines so that there are two or more paths connecting some junctions, but it’s wartime and budgets are tight. However, this may soon change as you’ve just been given some terrible news from double agents working in Ibmar: within the next month enemy spies plan to blow up one of the junctions! Unfortunately, the exact junction is not known, but knowing your enemy well you are certain that they will undoubtedly strike the critical junction, specifically the junction whose removal disconnects the most pairs of other remaining junctions in the system. You don’t have much time to act, so the most you can do is add one new line connecting two currently unconnected junctions, thereby reducing the number of disconnected pairs after the critical junction has been destroyed. Your job is to determine how to make the number of disconnected pairs as small as possible by adding in the best possible rail line.
Input
Input starts with a line containing an integer n (2 ≤ n ≤ 10 000) indicating the number of rail lines in the system. Following that are n lines of the form i1 i2 indicating that a rail line connects junctions i1 and i2. Junctions are numbered consecutively starting at 0. All rail lines are two-way and no rail line appears more than once in the input. There is exactly one path between any two junction points given in the input.
Output
Display two values n1 and n2, where n1 is the number of pairs of junctions which will be disconnected when the enemy destroys the critical junction, and n2 is the number of pairs of junctions still disconnected after you add in the best possible rail line. There will never be more than one critical junction.
Sample Input
6
0 1
1 2
2 3
2 4
4 5
4 6
Sample Output 1
11 5
Sample Input 2
2
2 1
0 1
Sample Output
1 0
题意
给n条边组成的无向图,点的坐标从0~n,且每两个点都有且只有一条边,删除某一个点时,且删除和该点所连得边,使得这个图分成了若干连通图,每个连通图都有ki个点,求n1:任意两个ki相乘加和后所能得到的最大值,求n2:n1减去两个最大的ki相乘
思路
题意可能比较难理解,所以多读几遍题。遇到很多次图上搜索点的个数的问题都不太会,于是打算写一下这个题。
代码中dfs的意思是计算删除这个点时的n1值,dfs2是求删除这个点时,所的连通图点数最多的两个图的点的个数。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int Maxn = 10005;
const int Maxm = 20005;
int head[Maxn];
bool vis[Maxn];
int num, n1, n2, n, p, max1 = -1, max2 = -2;
struct edge{
int to;
int next;
};
edge e[Maxm];//注意建立双向边需要开两倍
void addedge(int from, int to)
{
e[num].to = to;
e[num].next = head[from];
head[from] = num++;
}
int dfs(int s) //搜索每个点删去后的n1值
{
int t1 = 0,t = 0,ans = 0;
vis[s] = true;
for(int i = head[s]; i != -1; i = e[i].next)
{
int to = e[i].to;
if(!vis[to])
{
t1 = dfs(to);//每次dfs表示删除该点后,其中一个连通图中点的个数
t += t1;
ans += t1 * (n - t1);
//printf("%d %d %d\n", e[i].to, t1, ans);
}
}
ans += t * (n - t);
ans /= 2;
//printf("%d %d\n", s, ans);
if(ans>n1)
{
n1 = ans;
p = s;
}
return t+1;
}
int dfs2(int s)
{
int t = 0,t1 = 0;
vis[s] = true;
for(int i = head[s]; i != -1; i = e[i].next)
{
int to = e[i].to;
if(!vis[to])
{
t1 = dfs2(to);
t += t1;
//if(s == p)
// printf("%d %d\n",s, t1);
if(s == p && t1 > max1)
{
max2 = max1;
max1 = t1;
continue;
}
if(s == p && t1 <= max1 && t1 > max2)
max2 = t1;
}
}
return t+1;
}
int main()
{
int a,b;
num = 0;
memset(head, -1, sizeof(head));
memset(vis, false, sizeof(vis));
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
scanf("%d %d", &a, &b);
addedge(a, b);
addedge(b, a);
}
dfs(0);
memset(vis, false, sizeof(vis));
dfs2(p);
//printf("%d %d\n", max1, max2);
printf("%d %d\n", n1, n1 - max1*max2);
return 0;
}
如有错误请指明~ ฅ●ω●ฅ