標籤:
一筆畫問題時間限制:3000 ms | 記憶體限制:65535 KB難度:4
-
描述
-
zyc從小就比較喜歡玩一些小遊戲,其中就包括畫一筆畫,他想請你幫他寫一個程式,判斷一個圖是否能夠用一筆畫下來。
規定,所有的邊都只能畫一次,不能重複畫。
-
輸入
-
第一行只有一個正整數N(N<=10)表示測試資料的組數。
每組測試資料的第一行有兩個正整數P,Q(P<=1000,Q<=2000),分別表示這個畫中有多少個頂點和多少條連線。(點的編號從1到P)
隨後的Q行,每行有兩個正整數A,B(0<A,B<P),表示編號為A和B的兩點之間有連線。
-
輸出
-
如果存在合格連線,則輸出"Yes",
如果不存在合格連線,輸出"No"。
-
範例輸入
-
24 31 21 31 44 51 22 31 31 43 4
-
範例輸出
-
NoYes
思路:1、判斷聯通,用dfs或並查集都行
2、奇點個數為0或奇點個數為2,則可以一筆,否則需count/2筆
代碼:
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
using namespace std;
vector<int>mp[1005];
int vis[1005];
int num;
void dfs(int x)
{
vis[x]=1;
num++;
for(int i=0;i<mp[x].size();i++)
{
int v=mp[x][i];
if(!vis[v])
dfs(v);
}
}
int main()
{ int n,m,k;
cin>>n;
while(n--)
{
cin>>m>>k;
for(int i=0;i<=m;i++)
if(mp[i].size())
mp[i].clear();
int a,b;
for(int i=0;i<k;i++)
{
scanf("%d%d",&a,&b);
mp[a].push_back(b);
mp[b].push_back(a);
}
num=0;
int t=0;
for(int i=1;i<=m;i++)
if(mp[i].size()%2)
t++;
memset(vis,0,sizeof(vis));
dfs(b);
if(num==m&&(t==0||t==2))
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
return 0;
}
nyoj-一筆畫問題-歐拉圖+聯通判定