这个题与http://blog.csdn.net/anqier0468/article/details/9453567看起来没什么联系,但是贪心策略是一样的,(做这个题时还是没想起来),从度数为1的结点a开始算起,因为删除这个度数为1的结点肯定不如删除与它相连接的结点b效率高,所以一定是在与它相连的结点b上房哨兵,然后删除与b相连的边,直到没有度数为1的结点。特别注意只有一个结点时输出1。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#define MAXN 1510
using namespace std;
int main()
{
//freopen("in.txt","r",stdin);
int n,node[MAXN];
bool vis[MAXN];
while(scanf("%d",&n)!=EOF)
{
memset(node,0,sizeof(node));
vector<int>road[MAXN];
for(int i=0; i<n; i++)
{
int a,b,c;
scanf("%d:(%d)",&a,&b);
for(int j=0; j<b; j++)
{
cin>>c;
road[a].push_back(c);
road[c].push_back(a);
node[a]++;
node[c]++;
}
}
if(n==1)
{
cout<<1<<endl;
continue;
}
queue<int>st;
for(int i=0; i<n; i++)
if(node[i]==1)
st.push(i);
int sum=0;
memset(vis,false,sizeof(vis));
while(!st.empty())
{
int u=st.front();
st.pop();
if(vis[u]) continue;
for(int i=0; i<(int)road[u].size(); i++)
{
int t=road[u][i];
if(!vis[t])
{
vis[t]=1;
sum++;
for(int j=0; j<(int)road[t].size(); j++)
{
int q=road[t][j];
node[q]--;
if(node[q]==1&&!vis[q])
st.push(q);
}
}
}
}
cout<<sum<<endl;
}
return 0;
}