Legal path
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 354 Accepted Submission(s): 92
Problem Description
Given a directed graph ,every edge has a weight.
A legal route is defined as the list of edge, for every edge's weight should at least K greater than last edge's weight,if the last one exist. the length of a legal route is the total weight of the edge on it.
We should find the legal path from node 1
to node n
of minimum length.
A legal route is defined as the list of edge, for every edge's weight should at least K greater than last edge's weight,if the last one exist. the length of a legal route is the total weight of the edge on it.
We should find the legal path from node 1
Input
There is a number T
shows there are T test cases below. (T≤10
)
For each test case , the first line contains three integers n,m,K
,n,m
means the number of nodes and the number of edges on the graph. In following there arem
lines. Each line has three integer x,y,z
.
indicate that there is an edge frome x
to y
weighted z
.
2≤n≤100,000![]()
0≤m≤200,000![]()
1≤K,z≤1,000,000,000![]()
1≤x,y≤n![]()
For each test case , the first line contains three integers n,m,K
2≤n≤100,000
0≤m≤200,000
1≤K,z≤1,000,000,000
1≤x,y≤n
Output
For each case ,if there is no legal path from
1
to n
,
output -1 ,otherwise output the answer.
Sample Input
3 3 2 1 1 2 1 2 3 2 3 2 1 1 2 2 2 3 1 4 6 2 1 2 1 1 2 2 2 3 3 1 3 5 2 4 2 3 4 7
Sample Output
3 -1 11我的思路:类似于迪杰斯特拉算法的处理方式,dis[u]表示到达u节点的最小的legal path,pre[u]表示通过legal path到达u点时,u的入边。这样做松弛操作时,就会要多考虑一些情况,如果dis[u] + edge > dis[v],那么pre[v]=edge,如果dis[u] + edge = dis[v],说明v之前被更新过,找到最小的pre[v],因为这里要保证legal path最短,并且符合最优子结构,所以只需维护最小的pre即可.这里采用优先队列优化一直WA....还没有找到哪里错了#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int maxn = 100005; const __int64 inf = 0x3f3f3f3f*0x3f3f3f3f; struct Edge { int to,next; __int64 c; }edge[maxn<<2]; struct Node { int cur; __int64 dis,pre; Node(){} Node(__int64 _dis,__int64 _pre,int _cur) { dis = _dis; pre = _pre; cur = _cur; } friend bool operator < (Node a,Node b) { if(a.dis != b.dis) return a.dis > b.dis; return a.pre > b.pre; } }; int n,m; int head[maxn],tot; __int64 k,dis[maxn],pre[maxn]; bool vis[maxn]; priority_queue<Node> q; void init() { tot = 0; memset(head,-1,sizeof(head)); memset(vis,false,sizeof(vis)); for(int i = 1; i <= n; i++) dis[i] = pre[i] = inf; } void addedge(int u,int v,__int64 c) { edge[tot].to = v; edge[tot].c = c; edge[tot].next = head[u]; head[u] = tot++; } void Dijkstra(int src,int des) { while(!q.empty()) q.pop(); dis[src] = pre[src] = 0; Node now; q.push(Node(0,0,src)); while(!q.empty()) { now = q.top(); q.pop(); int u = now.cur; if(vis[u]) continue; vis[u] = true; for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if(vis[v] || (u != src && pre[u] + k > edge[i].c)) continue; if(dis[v] > dis[u] + edge[i].c) { dis[v] = dis[u] + edge[i].c; pre[v] = edge[i].c; q.push(Node(dis[v],pre[v],v)); } else if(dis[v] == dis[u] + edge[i].c && pre[v] > edge[i].c) { pre[v] = edge[i].c; q.push(Node(dis[v],pre[v],v)); } } } if(dis[des] == inf) printf("-1\n"); else printf("%I64d\n",dis[des]); } int main() { int t,u,v; __int64 c; scanf("%d",&t); while(t--) { scanf("%d%d%I64d",&n,&m,&k); init(); for(int i = 1; i <= m; i++) { scanf("%d%d%I64d",&u,&v,&c); addedge(u,v,c); addedge(v,u,c); } Dijkstra(1,n); } return 0; }
本文介绍了一种类似于迪杰斯特拉算法的处理方法,用于在一个带权有向图中寻找从节点1到节点n的最短合法路径。合法路径定义为路径上每条边的权重至少比前一条边的权重大K。

312

被折叠的 条评论
为什么被折叠?



