SPOJ UOFTCG - Office Mates (树的最小路径覆盖)

UOFTCG - Office Mates

no tags 

 

 

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−1

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≤50

, the number of test cases. Each test case begins with two integers on their own line: N≤100000, 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;
}

 

posted @ 2017-02-25 18:11  贱人方  阅读(338)  评论(0)    收藏  举报