2019ICPC南京网络赛H题Holy Grail

题目链接:https://nanti.jisuanke.com/t/41305

As the current heir of a wizarding family with a long history,unfortunately, you find yourself forced to participate in the cruel Holy Grail War which has a reincarnation of sixty years.However,fortunately,you summoned a Caster Servant with a powerful Noble Phantasm.When your servant launch her Noble Phantasm,it will construct a magic field,which is actually a directed graph consisting of n vertices and m edges.More specifically,the graph satisfies the following restrictions :

  • Does not have multiple edges(for each pair of vertices x and y, there is at most one edge between this pair of vertices in the graph) and does not have self-loops(edges connecting the vertex with itself).
  • May have negative-weighted edges.
  • Does not have a negative-weighted loop.
  • n<=300 , m<=500.

Currently,as your servant's Master,as long as you add extra 6 edges to the graph,you will beat the other 6 masters to win the Holy Grail.

However,you are subject to the following restrictions when you add the edges to the graph:

  • Each time you add an edge whose cost is c,it will cost you c units of Magic Value.Therefore,you need to add an edge which has the lowest weight(it's probably that you need to add an edge which has a negative weight).
  • Each time you add an edge to the graph,the graph must not have negative loops,otherwise you will be engulfed by the Holy Grail you summon.

Input

Input data contains multiple test cases. The first line of input contains integer t — the number of testcases (1≤t≤51 \le t \le 51≤t≤5).

For each test case,the first line contains two integers n,m,the number of vertices in the graph, the initial number of edges in the graph.

Then m lines follow, each line contains three integers x, y and w (0≤x,y<n0 \le x,y<n0≤x,y<n,−109-10^9−109≤w≤10910^9109, x=yx \not = yx​=y) denoting an edge from vertices x to y (0-indexed) of weight w.

Then 6 lines follow, each line contains two integers s,t denoting the starting vertex and the ending vertex of the edge you need to add to the graph.

It is guaranteed that there is not an edge starting from s to t before you add any edges and there must exists such an edge which has the lowest weight and satisfies the above restrictions, meaning the solution absolutely exists for each query.

Output

For each test case,output 666 lines.

Each line contains the weight of the edge you add to the graph.

样例输入:

1

10 15

4 7 10

7 6 3

5 3 3

1 4 11

0 6 20

9 8 25

3 0 9

1 2 15

9 0 27

5 2 0

7 3 -5

1 7 21

5 0 1

9 3 16

1 8 4

4 1

0 3

6 9

2 1

8 7

0 4

样例输出

-11

-9

-45

-15

17

7

题目翻译

作为一个有着悠久历史的巫师家族的现任继承人,

不幸的是,你发现自己被迫参加了一场残酷的圣杯战争,这场战争已经转世60年了。

然而,幸运的是,你召唤了一个拥有强大的贵族幻影的法师仆人。

当你的仆人发射她的贵族时Le Phantasm将构造一个魔域,它实际上是一个由n个顶点和m个边组成的有向图,

更具体地说,该图满足以下限制:              

不具有多条边(对于每对顶点X和Y,图形中这对顶点之间至多有一条边),

也不具有自循环(将顶点与其自身连接的边)。              

可能有负的加权边。              

没有负加权循环。              

n<=300,m<=500。              

目前,作为你仆人的主人,只要你在图上多加6条边,你就会击败其他6个主人赢得圣杯。            

 但是,在将边添加到图形中时,将受到以下限制:            

 每次添加一个成本为C的边,都会花费C单位的魔法值,因此需要添加一个重量最小的边(可能需要添加一个重量为负的边)。   每次你在图中添加一条边,图中不能有负的循环,否则你将被你召唤的圣杯吞没。

 

题目挺长的,其实就是很傻逼的一道签到题,当时读题干读了半天,还在想怎么解决添加边后形成负环的情况。

其实直接求y到x的最短路,如果为正输出负,为负输出正,然后再加上x到y的边就行了。

本来用floyd跑的,结果超了,改成spfa就可以A了,wdnmd,坑了我一个小时,多亏队友给力QAQ。

#include<bits/stdc++.h>
using namespace std;
const int  N = 105;
const int maxn = 0x3f3f3f3f;
int f[510][510];
int dis[500],vis[500];
int n, m;
int SPFA(int u,int v)
{
	queue<int>q;
	for (int i = 0; i < n; i++) {
		dis[i] = maxn;
		vis[i] = 0;
	}
	dis[u] = 0;
	vis[u] = 1;
	q.push(u);
	while (!q.empty()) {
		int s = q.front();
		q.pop();
		vis[s] = 0;
		for (int j = 0; j < n; j++) {
			if (dis[j] > dis[s] + f[s][j]) {
				dis[j] = dis[s] + f[s][j];
				//cout << dis[v] << endl;
				/*if (dis[v] > f[u][v])
					return 0;*/
				if (!vis[j]) {
					q.push(j);
					vis[j] = 1;
				}
			}
		}
	}
	return dis[v];
}
int main()
{
	ios::sync_with_stdio(0);
	int t;
	cin >> t;
	while (t--) {
		cin >> n >> m;
		memset(f, maxn, sizeof(f));
		for (int i = 1; i <= m; i++) {
			int x, y, z;
			cin >> x >> y >> z;
			f[x][y] = z;
		}
		for (int i = 1; i <= 6; i++) {
			int x, y;
			cin >> x >> y;
			/*int l = -1e9;
			int r = 1e9;
			while (l < r) {
				int mid = (l + r) / 2;
				cout << mid << endl;
				if (SPFA(x, y))
					r = mid - 1;
				else
					l = mid + 1;
			}*/
			int z = -SPFA(y, x);
			cout << z << endl;
			f[x][y] = z;
		}
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值