分量入度hdu 3836 Equivalent Sets
最近研究分量入度,稍微总结一下,以后继续补充:
hdu 2767 一样的目题
求加几条边可以使原图成一个强连通分量
思绪:先求出强连通分量个数,再求出每一个强连通分量的入度,度出
入度为0的个数和度出为0的个数,最大的那个就是要加的边
#include<stdio.h> #include<stack> #include<string.h> using namespace std; #define N 20001 #define inf 0x3fffffff int n,m,OP; int belong[N],dfs[N],low[N],ins[N],in[N],out[N]; struct op { int end; struct op *next; }*e[50002]; void addeage(int x,int y) { struct op *q=new op; q->end=y; q->next=e[x]; e[x]=q; } stack<int>Q; int ans,idx; void Tarjan(int x) { int v; dfs[x]=low[x]=idx++; Q.push(x); ins[x]=1; for(op *j=e[x];j;j=j->next) { if(dfs[j->end]==-1) { Tarjan(j->end); low[x]=low[x]>low[j->end]?low[j->end]:low[x]; } else if(ins[j->end]==1) low[x]=low[x]>dfs[j->end]?dfs[j->end]:low[x]; } if(low[x]==dfs[x]) { ans++; while(1) { v=Q.top(); Q.pop(); ins[v]=0; belong[v]=ans; if(v==x)break; } } } int main() { int i,j,x,y,z,t; while(scanf("%d%d",&n,&m)!=-1) { OP=0; for(i=0;i<=n;i++) { e[i]=NULL; dfs[i]=-1; ins[i]=0; out[i]=0; in[i]=0; } for(i=0;i<m;i++) { scanf("%d%d",&x,&y); addeage(x,y); } ans=idx=0; for(i=1;i<=n;i++) { if(dfs[i]==-1) Tarjan(i); } if(ans==1) { printf("0\n"); continue; } for(i=1;i<=n;i++) { for(op *j=e[i];j;j=j->next) { if(belong[i]!=belong[j->end]) { in[belong[j->end]]++; out[belong[i]]++; } } } int OP1=0; for(i=1;i<=ans;i++) { if(in[i]==0) OP1++; if(out[i]==0) OP++; } if(OP<OP1) OP=OP1; printf("%d\n",OP); } return 0; }
文章结束给大家分享下程序员的一些笑话语录:
自从有了Photoshop,我再也不相信照片了!(没有Photoshop的年代,胶片照片年代做假的也不少,那时候都相信假的!)