数据出水了,直接bfs也能过。
下面是我写的缩点+bfs的方法。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
/* Source Code Problem: 1003 Username: 2010201211 Run Time: 36MS Memory: 5188K Language:C++ JudgeStatus: Accepted */ #include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define V 1005 #define E 1005000 int n,m,dfn[V],low[V]; int top,cnt,indexs,ecnt; bool instack[V]; int stack[V],id[V],num[V],in[V],out[V],w[V],vis[V],queue[V],sum[V]; int map[V][V]; int head[V]; struct edge{ int s,t,cost,next; }e[E]; void addedge(int u,int v){ e[ecnt].s=u; e[ecnt].t=v; e[ecnt].next=head[u]; head[u]=ecnt++; } void tarjan(int u){ int v; int tmp; dfn[u]=low[u]=++indexs; instack[u]=true; stack[++top]=u; for(int k=head[u];k!=-1;k=e[k].next){ v=e[k].t; if(!dfn[v]){ tarjan(v); if(low[v]<low[u]) low[u]=low[v]; } else if(instack[v] && dfn[v]<low[u]){ low[u]=dfn[v]; } } if(dfn[u]==low[u]){ cnt++; do{ tmp=stack[top--]; instack[tmp]=false; id[tmp]=cnt; num[cnt]+=w[tmp]; } while(tmp!=u); } } void suodian(){ for(int i=1;i<=n;i++){ int tmp=id[i]; for(int k=head[i];k!=-1;k=e[k].next){ int tmp1=id[e[k].t]; if(id[i]!=id[e[k].t]){ out[tmp]++; in[tmp1]++; map[tmp][tmp1]=1; } } } /*cout <<"id:"; for(int i=1;i<=n;i++){ printf("%d ",id[i]); } cout << endl<<"in:"; for(int i=1;i<=cnt;i++){ printf("%d ",in[i]); } cout << endl<<"out:"; for(int i=1;i<=cnt;i++){ printf("%d ",out[i]); } cout << endl<<"num:"; for(int i=1;i<=cnt;i++){ printf("%d ",num[i]); } cout << endl;*/ } void bfs(int u){ memset(vis,0,sizeof(vis)); vis[u]=1; int v,head=0,tail=0; sum[u]+=num[u]; // cout << sum[u] << endl; queue[tail++]=u; while(head<tail){ v=queue[head++]; for(int i=1;i<=cnt;i++){ if(map[i][v]==1 && vis[i]==0){ vis[i]=1; sum[u]+=num[i]; //cout << sum[u] << endl; queue[tail++]=i; } } } } void findmax(){ int mmax=-1; int mmin=1050; for(int i=1;i<=cnt;i++){ if(out[i]==0){ bfs(i); if(sum[i]>mmax){ mmax=sum[i]; /*for(int j=1;j<=n;j++){ if(id[j]==i && j<mmin){ mmin=j; } }*/ } } } for(int i=1;i<=cnt;i++){ if(out[i]==0){ if(sum[i]==mmax){ for(int j=1;j<=n;j++){ if(id[j]==i && j<mmin){ mmin=j; } } } } } /*for(int i=1;i<=cnt;i++){ printf("%d ",sum[i]); } cout << endl;*/ printf("%d\n",mmin); } void solve(){ top=cnt=indexs=0; memset(dfn,0,sizeof(dfn)); memset(num,0,sizeof(num)); memset(sum,0,sizeof(sum)); memset(map,0,sizeof(map)); memset(id,0,sizeof(id)); memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); for(int i=1;i<=n;i++){ if(!dfn[i]) tarjan(i); } suodian(); findmax(); } int main() { //freopen("in.txt","r",stdin); int a,b; while(scanf("%d%d",&n,&m)!=EOF){ for(int i=1;i<=n;i++){ scanf("%d",&w[i]); } ecnt=0; memset(head,-1,sizeof(head)); for(int i=1;i<=m;i++){ scanf("%d%d",&a,&b); addedge(b,a); } solve(); } return 0; }