标签:
| input | output | 
|---|---|
| 3 3 1 2 2 3 3 1 | 3 | 
 分出中间那部分,剩下两部分可以相连,
分出中间那部分,剩下两部分可以相连,
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std;
typedef long long ll;
const int maxn=2002,maxm=200002;//ATTENTION,undirect
int n,m;
ll ans,nb;
int b[maxn];
int c[maxn];//edge to its father,select and acceed
int first[maxn];
int next[maxm];
bool tree[maxm];
int to[maxm];
int brg[maxm];//bridge
int dfn[maxn],high[maxn],depth;
bool up[maxn][maxn];
void dfs(int s,int aim){
        for(int p=first[s];p!=-1;p=next[p]){
                        if(tree[p]){
                                dfs(to[p],aim);
                        }
        }
        if(c[s]==1&&b[s]==b[aim]&&high[s]<dfn[aim]){
        //              printf("b:%d %d\n",aim,s);
                        ans++;
        }
       // return ans;
}
void addedge(int f,int t,int ind){
        next[ind]=first[f];
        first[f]=ind;
        to[ind]=t;
        swap(f,t);ind++;
        next[ind]=first[f];
        first[f]=ind;
        to[ind]=t;
}
void tarjan(int s,int pf){
        dfn[s]=++depth;
        for(int p=first[s];p!=-1;p=next[p]){
                if(s==to[p]){continue;}
                if(pf>=0&&to[p]==to[pf^1])c[s]++;
                if((p|1)==(pf|1)){b[s]++;continue;}
                if(dfn[to[p]]==0){
                        tree[p]=true;
                        tarjan(to[p],p);
                        if(b[to[p]]==1){
                                brg[nb++]=p;
                        }
                        b[s]+=b[to[p]]-1;
                        for(int i=1;i<=dfn[s];i++){
                                if(up[to[p]][i])up[s][i]=true;
                        }
                }
                else {
                        if(dfn[to[p]]>dfn[s]){
                                        b[s]--;
                        }
                        else {
                                        up[s][dfn[to[p]]]=true;
                                        b[s]++;
                        }
                }
        }
        high[s]=dfn[to[pf^1]];
        for(int i=dfn[to[pf^1]];i>=0;i--){
                if(up[s][i]){high[s]=i;break;}
        }
        if(b[s]==2)ans++;
        if(c[s]==1&&b[s]>1){
                for(int p=first[s];p!=-1;p=next[p]){
                        if(tree[p]){
                                dfs(to[p],s);
                        }
                }
        }
}
int main(){
        scanf("%d%d",&n,&m);
        memset(first,-1,sizeof(first));
        for(int i=0;i<m;i++){
                int f,t;
                scanf("%d%d",&f,&t);
                addedge(f,t,2*i);
        }
        tarjan(1,-1);
        ans+=(m-nb)*nb+nb*(nb-1)/2;
        printf("%I64d\n",ans);
        return 0;
}
URAL 1557 Network Attack 图论,连通性,tarjain,dfs建树,分类讨论 难度:2
标签:
原文地址:http://www.cnblogs.com/xuesu/p/4295579.html