算法设计课第六周作业

4. Pair

Description

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 ?

Input

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.

Output

For each test case, output a line containing “Yes” if there is a way to pair all the cities, or “No” otherwise.

Sample Input

2
6
3 4
6 5
4 6
2 1
6 2
6
3 4
2 1
4 6
4 2
6 5

Sample Output

Yes
Yes

思路

先把那些只有一条领边的城市先配对,在配对过程中会产生一些只有一条领边的城市,最后如果所有城市都能遍历到,就证明配对成功。

#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--)     //如果存在只有一条领边的城市
        {
            int delPoint = 0;   //找出只有一条邻边的城市
            for(; delPoint< pointCount; delPoint++)
            {
                if(pointLigature[delPoint] == 1)
                {
                    delPointNum += 2;
                    break;
                }
            }

            for(int i = 0; i < pointCount - 1; i++)     //找出与只有一条领边的城市连接的城市
            {
                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++)     //以只有一条领边的城市为中心,删掉与它相连的路径
            {
                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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值