题目:给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大。你只需要求出这个权值和。
允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次。
题目简述:先tarjan缩点,再从入度为零处进行一次拓扑排序,求最长路即可,话说拓扑排序求最长路真方便。。。
注意: 要明确拓扑的写法,要用栈写最优。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define man 100010 4 inline int sc() 5 { int x=0,f=1;char ch=getchar(); 6 while(!isdigit(ch)){ if(ch==45)f=-1;ch=getchar();} 7 while(isdigit(ch)) { x=x*10+ch-48;ch=getchar();} 8 return x*f; 9 } 10 /*TEST*/ 11 int n,m,c[man],x[man],y[man]; 12 /*EDGE*/ 13 int head[man<<1],num=0; 14 struct edge 15 { int next,to,dis;}e[man<<2]; 16 inline void add(int from,int to,int dis) 17 { e[++num].next=head[from]; 18 e[num].to=to; 19 e[num].dis=dis; 20 head[from]=num; 21 } 22 /*TARJAN*/ 23 int dfn[man],low[man],bel[man],val[man],cnt=0,dep=0; 24 bool vis[man]; 25 int sta[man],top=0; 26 void tarjan(int s) 27 { low[s]=dfn[s]=++dep;vis[s]=1;sta[++top]=s; 28 for(int i=head[s];i;i=e[i].next) 29 { int to=e[i].to; 30 if(!dfn[to]) 31 { tarjan(to); 32 low[s]=min(low[s],low[to]); 33 } 34 else if(vis[to]) 35 { low[s]=min(low[s],dfn[to]);} 36 } 37 if(low[s]==dfn[s]) 38 { int j;cnt++; 39 do 40 { j=sta[top--]; 41 vis[j]=0; 42 val[cnt]+=c[j]; 43 bel[j]=cnt; 44 }while(j!=s); 45 } 46 } 47 /*TOPSORT*/ 48 inline void clear() 49 { memset(e,0,sizeof(e)); 50 memset(head,0,sizeof(head)); 51 num=0; 52 } 53 int degree[man],dis[man],maxdis=-10; 54 inline void topsort() 55 { queue<int >q; 56 for(int i=1;i<=cnt;i++) 57 dis[i]=0; 58 for(int i=1;i<=cnt;i++) 59 if(degree[i]==0) q.push(i),dis[i]=val[i]; 60 while(q.size()!=0) 61 { int u=q.front();q.pop(); 62 for(int i=head[u];i;i=e[i].next) 63 { int to=e[i].to; 64 degree[to]--; 65 if(degree[to]==0) q.push(to); 66 dis[to]=max(dis[to],dis[u]+e[i].dis); 67 } 68 } 69 int ans=0; 70 for(int i=1;i<=cnt;i++) 71 ans=max(ans,dis[i]); 72 printf("%d\n",ans); 73 } 74 int main() 75 { n=sc();m=sc(); 76 for(int i=1;i<=n;i++) 77 c[i]=sc(); 78 for(int i=1;i<=m;i++) 79 { x[i]=sc(),y[i]=sc(); 80 add(x[i],y[i],0); 81 } 82 for(int i=1;i<=n;i++) 83 if(!dfn[i]) tarjan(i); 84 clear(); 85 for(int i=1;i<=m;i++) 86 { if(bel[ x[i] ]==bel[ y[i] ]) continue; 87 add(bel[x[i]],bel[y[i]],val[bel[y[i]]]); 88 degree[bel[y[i]]]++; 89 } 90 topsort(); 91 return 0; 92 }
时间: 2024-10-10 10:34:20