首页 > 代码库 > HDU 4479 权递增的最短路问题
HDU 4479 权递增的最短路问题
题目大意:
找一条节点 1 到节点 N 的最短路,保证这条路上每一条边都比前一条边长
dp[i] 表示在当前状态下1到i的最小值
先将所有边根据边的长度排一个序,再每次取出同一段相同长度的边去更新当前图中的每一个点可以更新的dp值,当然我们不能不能因为这相同的边长相互影响,所以不能边找边的同时边松弛dp值,因为可能 1-2:1 2-3:1,也就是说第一次其实不能由1到3这个点,但是你先更新1-2,那么2-3会因为2的dp值存在而可以松弛,所以,先找到所有可行的能进行迟缓的边记录在rec[]数组中,再把里面所有的边弛缓一遍
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 using namespace std; 6 const int N = 10005; 7 typedef long long LL; 8 LL dp[N]; 9 int n , m , k;10 11 struct Path{12 int x,y,d;13 bool operator<(const Path &m)const{14 return d < m.d;15 }16 }p[100005];17 18 struct Rec{19 int x,y;20 LL d;21 Rec(int x=0,int y=0,LL d=0):x(x),y(y),d(d){}22 }rec[100005];23 24 void update(int l , int r)25 {26 int t = 0;27 28 for(int i=l;i<=r;i++){29 int u = p[i].x , v = p[i].y;30 if(dp[u] >= 0 && (dp[v] > dp[u] + p[i].d || dp[v] < 0))31 {32 rec[t++] = Rec(u,v, dp[u] + p[i].d);33 }34 if(dp[v] >= 0 && (dp[u] > dp[v] + p[i].d || dp[u] < 0))35 {36 rec[t++] = Rec(v,u, dp[v] + p[i].d);37 }38 }39 40 for(int i=0;i<t;i++){41 int u = rec[i].x , v = rec[i].y;42 if(dp[v] > rec[i].d || dp[v] < 0)43 {44 dp[v] = rec[i].d;45 }46 }47 }48 49 void add_edge(int x,int y,int d)50 {51 p[k].x = x , p[k].y = y , p[k++].d = d;52 }53 54 void solve()55 {56 sort(p,p+k);57 memset(dp,-1,sizeof(dp));58 dp[1] = 0;59 int l=0;60 for(int r=1 ; r<k;r++){61 if(p[r].d != p[r-1].d){62 update(l , r-1);63 l=r;64 }65 }66 update(l,k-1);67 if(dp[n] < 0)68 puts("No answer");69 else70 printf("%I64d\n",dp[n]);71 }72 73 int main()74 {75 // freopen("test.in","rb",stdin);76 77 int T,a,b,d;78 scanf("%d",&T);79 while(T--){80 scanf("%d%d",&n,&m);81 82 k=0;83 memset(G , -1 , sizeof(G));84 for(int i=0;i<m;i++){85 scanf("%d%d%d",&a,&b,&d);86 add_edge(a,b,d);87 }88 solve();89 }90 return 0;91 }
HDU 4479 权递增的最短路问题
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。