POJ 3249 Test for Job
阿新 • • 發佈:2018-11-09
演算法:記憶化搜尋/最長路(我覺得可以用SPFA)(點權轉)邊權寫的不錯
難度:NOIp--
簡述題意:n個點m條邊的有向圖。每一個點有權值,如今從入度為零的點出發到出度為零的點。求路徑上的權值之和最大為多少。
程式碼如下:
tiao xi 了半天,居然要預設多組資料讀入,POJ**
#include <cstdio> #include <iostream> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #define ll long long #define N 100005 #define M 1000005 using namespace std; int va[N]; struct node { int next; int to; }edg[M]; int head[N]; int f[N]; int ind[N]; int cnt=1; void init() { memset(head,-1,sizeof(head)); memset(ind,0,sizeof(ind)); memset(f,0,sizeof(f)); cnt=1; } void add(int u,int v) { edg[cnt].next=head[u]; edg[cnt].to=v; head[u]=cnt++; } int dfs(int rt) { if(f[rt]) return f[rt]; ll maxn=-0x3f3f3f3f; for(int i = head[rt];i != -1;i=edg[i].next) { int to=edg[i].to; maxn=max(maxn,1ll*dfs(to)); } if((int)maxn==-0x3f3f3f3f) maxn=0; f[rt]=maxn+va[rt]; return f[rt]; } int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { init(); for(int i = 1;i <= n;i++) { scanf("%d",&va[i]); } for(int i = 1;i <= m;i++) { int x,y; scanf("%d%d",&x,&y); add(x,y); ind[y]++; } ll ans=-0x3f3f3f3f; for(int i = 1;i <= n;i++) { if(!ind[i]) { ans=max(ans,1ll*dfs(i)); } } printf("%lld\n",ans); } } /* 5 6 1 1 3 4 2 1 2 1 3 3 4 5 4 5 1 2 3 */