0
点赞
收藏
分享

微信扫一扫

hdu 5168(最短路----待解决)

cnlinkchina 2023-05-29 阅读 61


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


 



Input


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 are m 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


 



Output


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;
}



举报

相关推荐

0 条评论