<Sicily>Pair

来源:互联网 发布:数据比例图 编辑:程序博客网 时间:2024/04/28 10:08

一、题目描述

The N cities of Estiah are connected by N-1 roads. The roads are built in a way that it’s always possible to travel between any two cities.

Now the king of Estiah wants to pair adjacent cities into defending units. Two cities are adjacent if they are connected directly by a road. Each defending unit consists of exactly two cities, and each city can never be paired into two different defending units.
What the king wants to know is if it’s possible to have all the cities paired into defending units. Can you help him ?

二、输入

The input consists of several test cases.
The first line of the input is an positive integer indicating the number of test cases following.
Each test case starts with an positive integer N (1<=N<=10000) , which is the number of cities. Cities are numbered from 1 to N.
The next N-1 lines each contains two positive integer A and B, indicating that there is a road connecting city A and city B.

三、输出

For each test case, output a line containing “Yes” if there is a way to pair all the cities, or “No” otherwise.
例如:
输入:
2
6
3 4
6 5
4 6
2 1
6 2
6
3 4
2 1
4 6
4 2
6 5
输出:
Yes
Yes

四、解题思路

题中愿意是:有N个点,n-1条边使n个点组成连通图。从题中能够看出,这是一个最小生成树。题中要求,没相连的两个城市可以组成一组,而且每个城市只能归于一组。

思路:
从图中找出其中一个度为1的点,删掉该点与和该点相连的另外一个点,已经与他们相连的边。不断重复该步骤,直到不存在度为1的点,如果已经全部配对完,表示能配对,否则不能配对。

步骤:
1、找出图中其中一个度为1的点,如下图点“1”
这里写图片描述

2、找到与点1相连的那个点,点“2”
这里写图片描述

3、删掉与点“2”相连的所有的边
这里写图片描述

4、找出图中其中一个度为1的点,如下图点“3”
这里写图片描述

5、找到与点3相连的那个点,点“4”
这里写图片描述

6、删掉与点“4”相连的所有的边
这里写图片描述

7、找出图中其中一个度为1的点,如下图点“5”
这里写图片描述

8、找到与点5相连的那个点,点“6”
这里写图片描述

9、删掉与点“6”相连的所有的边
因为已经配对完所有的点,所以能成功配对

五、代码

#include<iostream>using namespace std;int main(){    int times;    cin >> times;    while(times--)    {        int pointCount;     //城市的个数        int delPointNum = 0;    //已经能配对好的城市个数        cin >> pointCount;        int edgeArray[pointCount][2];   //保存相连的两个城市        int pointLigature[pointCount];  //连接每个城市的度        for(int i = 0; i < pointCount; i++)        {            pointLigature[i] = 0;        }        for(int i = 0; i < pointCount - 1; i++)        {            int startPoint, endPoint;            cin >> startPoint >> endPoint;            edgeArray[i][0] = startPoint;            edgeArray[i][1] = endPoint;            pointLigature[startPoint - 1]++;            pointLigature[endPoint - 1]++;        }        if(pointCount % 2 == 1) {cout << "No" << endl;continue;}    //如果城市的个数是奇数个直接判断不能配对        int maxDelTime = pointCount;        while(maxDelTime--)     //如果存在着度为1的顶点(城市),每次循环都会配对(删掉)一对        {            int delPoint = 0;   //找出度为1的顶点            for(; delPoint< pointCount; delPoint++)            {                if(pointLigature[delPoint] == 1)                {                    delPointNum += 2;                    break;                }            }            for(int i = 0; i < pointCount - 1; i++)     //找出与度为1的顶点相连的顶点            {                if(edgeArray[i][0] == delPoint + 1) {delPoint = edgeArray[i][1]; break;}                if(edgeArray[i][1] == delPoint + 1) {delPoint = edgeArray[i][0]; break;}            }            for(int i = 0; i < pointCount - 1; i++)     //以与度为1的顶点相连的顶点为中心,删掉与它相连的路径            {                if(edgeArray[i][0] == delPoint || edgeArray[i][1] == delPoint)                {                    int point;                    point = edgeArray[i][0] - 1;                    pointLigature[point]--;                    point = edgeArray[i][1] - 1;                    pointLigature[point]--;                    edgeArray[i][0] = 0;                    edgeArray[i][1] = 0;                }            }        }        if(delPointNum >= pointCount) cout << "Yes" << endl;        else cout << "No" << endl;    }    return 0;}
0 0
原创粉丝点击