题意:给你n个点,然后你要算出删除每个点后有多少个联通块,然后输出前m个,顺序是优先输出形成联通块多的,假如有数量相同,优先输出先输入的。
思路:参考了一下别人的思路,用tarjan时就可以求出联通块的数量。
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
#define MAX 5000
bool Map[MAX+10][MAX+10],vis[MAX+10];
int low[MAX+10],dfn[MAX+10],value[MAX+10];
int n,m;
int c=0;
void dfs(int u,int pre)
{
vis[u]=1;
low[u]=dfn[u]=++c;
for(int i=1;i<=n;i++)
{
if(Map[u][i])
{
if(!vis[i])
{
dfs(i,u);
low[u]=min(low[u],low[i]);
}
else if(i!=pre)
low[u]=min(low[u],dfn[i]);
}
}
}
int main()
{
cin.sync_with_stdio(false);
int temp1,temp2;
while(cin>>n>>m)
{
memset(Map,0,sizeof(Map));
while(m--)
{
cin>>temp1>>temp2;
Map[temp1][temp2]=Map[temp2][temp1]=1;
}
memset(vis,0,sizeof(vis));memset(low,0,sizeof(low));memset(dfn,0,sizeof(dfn));memset(value,0,sizeof(value));
c=0;
dfs(1,1);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(Map[i][j])
if(low[i]!=low[j])
{
value[low[j]]++;
}
int ans=count(value,value+n+1,1);
cout<<(ans+1)/2<<'\n';
}
return 0;
}