#include<bits/stdc++.h> using namespace std; /* * 有两种可能 * 如果只有一个连通分量则不需要坐出租车 * 答案为0 2*N-2或者m*2 也就是边数的两倍 * 如果有多个连通分量 * 则每个连通分量的公交车最小次数实际是2*n-2-d n是这个连通分量的节点个数 d是这个连通分量的直径 * 这里是生成树 也就是树的直径 */ const int maxN=1e5+5; vector<int> G[maxN]; int cnt_node[maxN]; bool vis[maxN]; int maxd,N; int dfs(int x,int f,int d,int n,int & r){ vis[x]=true; int cnt=0; if(d>maxd){ r=x; maxd=d; } for(int i=0;i<G[x].size();i++){ if(G[x][i]!=f)cnt+=dfs(G[x][i],x,d+1,n,r); } return cnt+1; } int main(){ memset(vis,0,sizeof(vis)); memset(cnt_node,0,sizeof(cnt_node)); int m,cnt=0,a,b,res=0; scanf("%d%d",&N,&m); for(int i=0;i<m;i++){ scanf("%d%d",&a,&b); G[a].push_back(b); G[b].push_back(a); } if(N==m+1){ printf("0 %d",N*2-2); return 0; } maxd=0; int r1,r2; for(int i=1;i<=N;i++)if(!vis[i]){ maxd=0; r1=r2=i; cnt_node[++cnt]=dfs(i,i,0,cnt,r1); maxd=0; dfs(r1,r1,0,cnt,r2); res+=cnt_node[cnt]*2-maxd-2; } printf("%d %d",cnt,res); }
EOJ 3497 group
猜你喜欢
转载自www.cnblogs.com/TAMING/p/9400238.html
今日推荐
周排行