首页 > 代码库 > SPOJ UOFTCG - Office Mates (树的最小路径覆盖)
SPOJ UOFTCG - Office Mates (树的最小路径覆盖)
UOFTCG - Office Mates
Dr. Baws has an interesting problem. His N
graduate students, while friendly with some select people, are generally not friendly with each other. No graduate student is willing to sit beside a person they aren‘t friends with.
The desks are up against the wall, in a single line, so it‘s possible that Dr. Baws will have to leave some desks empty. He does know which students are friends, and fortunately the list is not so long: it turns out that for any subset of K
graduate students, there are at most K
pairs of friends. Dr. Baws would like you to minimize the total number of desks required. What is this minimum number?
Input
The input begins with an integer T
, the number of test cases. Each test case begins with two integers on their own line: N, the number of graduate students (who are indexed by the integers 1 through N), and M, the number of friendships among the students. Following this are M lines, each containing two integers i and j separated by a single space. Two integers i and j represent a mutual friendship between students i and j
.
The total size of the input file does not exceed 2 MB.
Output
For each test case output a single number: the minimum number of desks Dr. Baws requires to seat the students.
Example
Input:
1
6 5
1 2
1 3
1 4
4 5
4 6
Output:
7
Explanation of Sample:
As seen in the diagram, you seat the students in two groups of three with one empty desk in the middle.
【分析】有一群人,有的人互为朋友,现在有一排椅子,将这些人安排在椅子上,要求不是朋友的两个人不能坐在一起,即可以将他俩隔开或者中间放个空的椅子。
已知K个人最多有K-1对朋友。问最少需要多少椅子。
树的最小路径覆盖模板题。
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> #include <string> #include <map> #include <stack> #include <queue> #include <vector> #define inf 0x3f3f3f3f #define met(a,b) memset(a,b,sizeof a) #define pb push_back typedef long long ll; using namespace std; const int N = 200050; const int M = 24005; const int mod=1e9+7; int n,m; int T,cnt; int head[N],ans[N],vis[N]; bool mark[N]; struct edge{int to,next;}edg[N*2]; void add(int u,int v) { edg[++cnt].to=v;edg[cnt].next=head[u];head[u]=cnt; edg[++cnt].to=u;edg[cnt].next=head[v];head[v]=cnt; } void dfs(int x,int f) { ans[x]=vis[x]=1; int tot=0; for(int i=head[x];i!=-1;i=edg[i].next) { if(edg[i].to==f)continue; dfs(edg[i].to,x); ans[x]+=ans[edg[i].to]; if(!mark[edg[i].to])tot++; } if(tot>=2)ans[x]-=2,mark[x]=1; else if(tot==1)ans[x]--; } int main() { int u,v; scanf("%d",&T); while(T--) { cnt=0; met(head,-1); met(ans,0); met(mark,0); met(vis,0); scanf("%d%d",&n,&m); while(m--) { scanf("%d%d",&u,&v); add(u,v); } int anss=0,ret=0;; for(int i=1;i<=n;i++){ if(!vis[i]){ ret++; dfs(i,0); vis[i]=1; anss+=ans[i]-1; } } printf("%d\n",anss+ret-1+n); } return 0; }
SPOJ UOFTCG - Office Mates (树的最小路径覆盖)