赞
踩
https://codeforces.com/contest/1000/problem/E
给出一张图,设两点s,t,则可在s,t两点间的必经之边(去掉这条边,s、t不可达)上放置怪物,找到s、t,使得它可放置最多的怪物。输出可放置的最多的怪物。
利用tarjan求出该图的所有边-双连通分量,缩点,形成一棵树,求出树的直径,得到答案。
- #include <bits/stdc++.h>
- #define ll long long
- using namespace std;
- const int maxn=3e5+10;
- void read(int &x){
- int f=1;x=0;char s=getchar();
- while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
- while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
- x*=f;
- }
- struct Edge
- {
- int no,v,next;
- }edges[2*maxn];
-
- int n,m,ebcnum; //节点数目,无向边的数目,边_双连通分量的数目
- int e,head[maxn];
- int pre[maxn]; //第一次访问的时间戳
- int dfs_clock; //时间戳
- int isbridge[maxn*2],cl[maxn]; //标记边是否为桥
- vector<int> ebc[maxn]; //边_双连通分量
- vector<int>mp[maxn];
- set<int>ss[maxn];
- void addedges(int num,int u,int v) //加边
- {
- edges[e].no = num;
- edges[e].v = v;
- edges[e].next = head[u];
- head[u] = e++;
- edges[e].no = num++;
- edges[e].v = u;
- edges[e].next = head[v];
- head[v] = e++;
- }
-
- int dfs_findbridge(int u,int fa) //找出所有的桥
- {
- int lowu = pre[u] = ++dfs_clock;
- for(int i=head[u];i!=-1;i=edges[i].next)
- {
- int v = edges[i].v;
- if(!pre[v])
- {
- int lowv = dfs_findbridge(v,u);
- lowu = min(lowu,lowv);
- if(lowv > pre[u])
- {
- isbridge[edges[i].no] = 1; //桥
- }
- }
- else if(pre[v] < pre[u] && v != fa)
- {
- lowu = min(lowu,pre[v]);
- }
- }
- return lowu;
- }
-
- void dfs_coutbridge(int u,int fa){
- ebc[ebcnum].push_back(u);
- pre[u] = ++dfs_clock;
- for(int i=head[u];i!=-1;i=edges[i].next)
- {
- int v = edges[i].v;
- if(!isbridge[edges[i].no] && !pre[v]) dfs_coutbridge(v,u);
- }
- }
-
- void init()
- {
- memset(pre,0,sizeof(pre));
- memset(isbridge,0,sizeof(isbridge));
- memset(head,-1,sizeof(head));
- e = 0; ebcnum = 1;
- }
-
- int dep[maxn],vis[maxn],ans=0;
- //vector<int>tem;
- void dfs(int u){
- int i,l1=0,l2=0,f=0;
- for(i=0;i<mp[u].size();i++){
- int v=mp[u][i];
- if(!vis[v]){
- f=1;
- vis[v]=1;
- dfs(v);
- if(l1==0){
- l1=dep[v]+1;
- }
- else if(dep[v]+1>l1){
- l2=l1;
- l1=dep[v]+1;
- }
- else if(dep[v]+1>l2){
- l2=dep[v]+1;
- }
- }
- }
- if(!f){
- dep[u]=0;return;
- }
- ans=max(ans,l1+l2);
- dep[u]=l1;
- }
-
-
- int ui[maxn],vi[maxn];
- int main(){
- int i,j;
- read(n);read(m);
- init();
- for(i=0;i<m;i++){
- read(ui[i]);read(vi[i]);
- addedges(i,ui[i],vi[i]);
- }
- dfs_findbridge(1,-1);
- memset(pre,0,sizeof(pre));
- for(i=1;i<=n;i++){
- if(!pre[i]){
- ebc[ebcnum].clear();
- dfs_coutbridge(i,-1);
- ebcnum++;
- }
- }
- ebcnum--;
- for(i=1;i<=ebcnum;i++){
- for(j=0;j<ebc[i].size();j++){
- int u=ebc[i][j];
- cl[u]=i;
- }
- }
- for(i=0;i<m;i++){
- int x=cl[ui[i]],y=cl[vi[i]];
- if(!ss[x].count(y)){
- ss[x].insert(y);
- mp[x].push_back(y);
- }
- if(!ss[y].count(x)){
- ss[y].insert(x);
- mp[y].push_back(x);
- }
- }
- memset(vis,0,sizeof(vis));
- memset(dep,0,sizeof(dep));
- vis[1]=1;
- dfs(1);
- cout<<ans;
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。