uva 11080
题意:放最少的士兵去监视所有的道路, 但士兵不可相邻
分析:由於不可相邻可以視同為不可同色(分成两种颜色), 对于一個连通图而言, 如果可以用两种颜色涂完,
那么较少使用的顏色则是放置士兵的个数。这题要小心有很多连通图 !
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<cstdlib> #include<queue> #include<vector> #include<stack> #include<set> using namespace std; vector<int> e[205]; int n,m,vis[205],stk[205],k; bool dfs(int u) { stk[++k]=u; for(int i=0;i<e[u].size();i++) { int v=e[u][i]; if(vis[v]==0) { vis[v]=3-vis[u]; if(!dfs(v)) return false; } else { if(vis[v]==vis[u]) return false; } } return true; } int main() { int tt; scanf("%d",&tt); while(tt--) { int ans=0; scanf("%d%d",&n,&m); for(int i=0;i<n;i++) e[i].clear(); memset(vis,0,sizeof(vis)); for(int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); e[x].push_back(y); e[y].push_back(x); } bool flag=true; for(int i=0;i<n;i++) { if(vis[i]==0) { k=0; int cnt=0; vis[i]=1; if(!dfs(i)) { flag=false; break; } for(int i=1;i<=k;i++) { if(vis[stk[i]]==1) cnt++; } cnt=min(cnt,k-cnt); if(k==1) cnt=1; ans+=cnt; } } if(!flag) printf("-1\n"); else printf("%d\n",ans); } return 0; }