1. 程式人生 > >2018.09.15 hdu3018Ant Trip(尤拉路)

2018.09.15 hdu3018Ant Trip(尤拉路)

傳送門 顯然答案等於各個連通分量的筆畫數之和。 因此我們dfs每個連通分量計算對答案的貢獻。 對於一個連通分量,如果本來就有歐拉回路那麼只需要一筆。 否則需要寄點數/2那麼多筆才能畫完。 知道這個結論這題就很簡單了。 程式碼;

#include<bits/stdc++.h>
#define N 100005
#define M 200005
using namespace std;
inline int read(){
    int ans=0;
    char ch=getchar();
    while(!isdigit(ch))ch=getchar();
    while
(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar(); return ans; } int n,m,first[N],ans,cnt,tot1,tot2,du[N]; bool vis[N]; struct edge{int v,next;}e[M<<1]; inline void add(int u,int v){e[++cnt].v=v,e[cnt].next=first[u],first[u]=cnt;} inline void init(){ memset(first,0,sizeof
(first)); memset(du,0,sizeof(du)); memset(vis,false,sizeof(vis)); cnt=ans=0; } inline void dfs(int p,int fa){ vis[p]=true,++tot1; if(du[p]&1)++tot2; for(int i=first[p];i;i=e[i].next){ int v=e[i].v; if(vis[v])continue; dfs(v,p); } } int main(){ while
(~scanf("%d%d",&n,&m)){ init(); for(int i=1;i<=m;++i){int u=read(),v=read();++du[u],++du[v],add(u,v),add(v,u);} for(int i=1;i<=n;++i){ if(!vis[i]){ tot1=tot2=0,dfs(i,0); ans+=tot2?tot2/2:1; } } printf("%d\n",ans); } return 0; }