Holy Grail
限制1000 ms 256 MB
As the current heir of a wizarding family with a long history,unfortunately, you fifind yourself forced to participate in the cruel Holy Grail War which has a reincarnation of sixtyyears.However,fortunately,you summoned a Caster Servant with a powerful Noble Phantasm.When your servant launch her Noble Phantasm,it will construct a magic fifield,which is actually a directed graph consisting of n vertices and m edges.More
specififically,the graph satisfifies 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 test cases (1 ≤ t ≤ 5). For each test case,the fifirst 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 < n,−109≤w≤ 109, x = 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 satisfifies the above
restrictions, meaning the solution absolutely exists for each query.
Output :
For each test case,output 6 lines.
Each line contains the weight of the edge you add to the graph.
Sample Input:
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
Sample Output:
-11
-9
-45
-15
177
2019CCPC区域赛南京网络赛H题。
题目太长,简单解释一下:
有t组样例,每组有n个点和m条边(单向),下面是6组询问,从第一个点到第二个点, 连一条路,要最短,且无负环(第二次询问是第一条边已经加入原图)。
题解:
直接SPFA跑最短路,然后取相反数(只要最短,一定无负环)。
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const ll inf=99999999999999;
ll dis[511],a[511][511],b[301][511];
void spfa(int s)//可以当作SPFA的模板
{
for(int i=1; i<=b[s][0]; i++) //b[s][0]是s点连接了几个其他点
if (dis[b[s][i]]>dis[s]+a[s][b[s][i]])
{
dis[b[s][i]]=dis[s]+a[s][b[s][i]];
spfa(b[s][i]);
}
}
int main()
{
int t;
cin>>t;
while(t--)
{
for(int i=0;i<=510;i++)
{
for(int j=0;j<=510;j++)
{
a[i][j]=inf;
}
}
for(int i=0;i<=510;i++)
{
dis[i]=inf;
}
memset(b,0,sizeof(b));
int n,m;
scanf("%d%d",&m,&n);
for(int i=1;i<=n;i++)
{
int x,y;
long long z;
scanf("%d%d%lld",&x,&y,&z);
a[x][y]=z;
b[x][0]++;
b[x][b[x][0]]=y;
}
for(int i=1;i<=6;i++)
{
for(int i=0;i<=510;i++)
{
dis[i]=inf;
}
int u,v;
cin>>u>>v;
dis[v]=0;
spfa(v);
a[u][v]=-1*dis[u];
b[u][0]++;
b[u][b[u][0]]=v;
printf("%lld\n",-1*dis[u]);
}
}
return 0;
}