1. 程式人生 > >CodeForces 459E Pashmak and Graph:dp + 貪心

CodeForces 459E Pashmak and Graph:dp + 貪心

clu return include rap for stream void {} mes

題目鏈接:http://codeforces.com/problemset/problem/459/E

題意:

  給你一個有向圖,每條邊有邊權。

  讓你找出一條路徑,使得這條路徑上的邊權嚴格遞增。

  問你這樣的路徑最長有多長。

題解:

  先將所有邊按邊權從小到大排序,以保證邊權遞增。

  表示狀態:

    dp[i] = max len

    表示以點i為終點時的最長路徑長度。

  找出答案:

    ans = max dp[i]

  如何轉移:

    枚舉每條邊e[i],則有:

      dp[e[i].t] = max(dp[e[i].t], dp[e[i].s]+1)

    但是要註意,當枚舉一些邊的邊權相同時,直接更新dp[e[i].t]是不行的。

    比如一條鏈上的邊權均相同的情況。

    所以當邊權相同時,先暫時將新的dp[e[i].t]存到f數組中,等這些邊權相同的邊枚舉完之後,再用f數組更新dp。

  邊界條件:

    set dp & f = 0

AC Code:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <algorithm>
 5
#include <vector> 6 #define MAX_N 300005 7 8 using namespace std; 9 10 struct Edge 11 { 12 int s; 13 int t; 14 int len; 15 Edge(int _s,int _t,int _len) 16 { 17 s=_s; 18 t=_t; 19 len=_len; 20 } 21 Edge(){} 22 friend bool operator
< (const Edge &a,const Edge &b) 23 { 24 return a.len<b.len; 25 } 26 }; 27 28 int n,m; 29 int ans=0; 30 int f[MAX_N]; 31 int dp[MAX_N]; 32 Edge edge[MAX_N]; 33 34 void read() 35 { 36 scanf("%d%d",&n,&m); 37 int a,b,v; 38 for(int i=0;i<m;i++) 39 { 40 scanf("%d%d%d",&a,&b,&v); 41 edge[i]=Edge(a,b,v); 42 } 43 } 44 45 void work() 46 { 47 sort(edge,edge+m); 48 memset(dp,0,sizeof(dp)); 49 memset(f,0,sizeof(f)); 50 int pos=0; 51 for(int i=0;i<m;i++) 52 { 53 Edge temp=edge[i]; 54 f[temp.t]=max(f[temp.t],dp[temp.s]+1); 55 ans=max(ans,f[temp.t]); 56 if(i==m-1 || temp.len!=edge[i+1].len) 57 { 58 while(pos<=i) 59 { 60 dp[edge[pos].t]=f[edge[pos].t]; 61 pos++; 62 } 63 } 64 } 65 printf("%d\n",ans); 66 } 67 68 int main() 69 { 70 read(); 71 work(); 72 }

CodeForces 459E Pashmak and Graph:dp + 貪心