hdu3018 Ant Trip

        题意:拓展一笔画问题。给一个无向图,每条边只能经过一次,问多少笔能将图画完。孤立的点不用考虑。

        思路:先把每个连通分量找出来,然后数这个连通分量的度为奇数的点,如果该连通分量是欧拉通路,显然可以一笔画,否则需要次数是奇度点数量/2。


#include <iostream>             
#include <stdio.h>             
#include <cmath>             
#include <algorithm>             
#include <iomanip>             
#include <cstdlib>             
#include <string>             
#include <memory.h>             
#include <vector>             
#include <queue>             
#include <stack>             
#include <map>           
#include <set>           
#include <ctype.h>
#define ll long long         
#define max3(a,b,c) max(a,max(b,c)) 
using namespace std;    


vector<int> mp[100010];
int deg[100010];

int p[100010];//标记连通分量 
int odd[100010];


int main(){
	int n,m;
	while(cin>>n>>m){
		//init
		memset(p,-1,sizeof(p));
		memset(mp,0,sizeof(mp));
		memset(deg,0,sizeof(deg));
		memset(odd,0,sizeof(odd));
		//
		for(int i=1;i<=m;i++){
			int u,v;
			scanf("%d%d",&u,&v);
			deg[u]++; deg[v]++;
			mp[u].push_back(v);
			mp[v].push_back(u);
		}
		
		int cnt=0;
		for(int i=1;i<=n;i++){
			
			if(p[i]==-1){
				if(!deg[i])continue;//无视孤立的点 
				cnt++;
				p[i]=cnt;
				
			}else{
				continue;
			}
			queue<int> que; que.push(i);
			while(!que.empty()){
				int cur=que.front(); que.pop();
				int siz=mp[cur].size();
				for(int j=0;j<siz;j++){
					int v=mp[cur][j];
					if(p[v]!=-1)continue;
					que.push(v);
					p[v]=cnt;
				}
			}
		}
		
		for(int i=1;i<=n;i++){
			if(deg[i]&1){
				odd[p[i]]++;
			}
		}
		int ans=0;
		for(int i=1;i<=cnt;i++){
			ans+=max(1,(odd[i]/2));
		}
		cout<<ans<<endl;
	}
	return 0;
}


你可能感兴趣的:(欧拉通路)