前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2019 ICPC 南京网络赛 H-Holy Grail

2019 ICPC 南京网络赛 H-Holy Grail

作者头像
风骨散人Chiam
发布2020-10-28 10:17:33
4590
发布2020-10-28 10:17:33
举报
文章被收录于专栏:CSDN旧文CSDN旧文

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 \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 \le x,y<n0≤x,y<n,-10^9−109≤w≤10^9109, x \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 66 lines.

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

这个题,我收获很大,不是在算法上的提升,而是在与对于自己的学习方式的改进,这个题暴露出诸多问题,如下:

1.对于自己写的模板,没有经过验证,使用起来,漏洞百出。

2.对于用别人的模板,看着难受,改起来费劲容易出错。

3.鉴于上一条,就要写第一条,所以以后改板子,写板子都要记下来,最好是每次自己写,现在有点后悔。

所以导致超时4遍,wa了4遍,所以吸取我的教训,除了非常固定的模板,其他都自己写,养成习惯,每次写都是对于这个算法思想的再认识。

这个题目的思路我是秒出的,因为打眼一看就能看出这个题目说的是带负边权的最短路问题,现在我们将范围缩小,只剩下了SPFA,Bellman-ford,和Floyd。 虽然这个题Floyd能过,但是不是这个题的正解。这个题首选的是bellman 或者SPFA,然后就是求填边之后的非负最小环问题。共跑6遍Bellman-ford

代码语言:javascript
复制
#include<iostream>
#include<queue>
#include<algorithm>
#include<set>
#include<cmath>
#include<vector>
#include<map>
#include<stack>
#include<bitset>
#include<cstdio>
#include<cstring>
#define Swap(a,b) a^=b^=a^=b
#define cini(n) scanf("%d",&n)
#define cinl(n) scanf("%lld",&n)
#define cinc(n) scanf("%c",&n)
#define cins(s) scanf("%s",s)
#define coui(n) printf("%d",n)
#define couc(n) printf("%c",n)
#define coul(n) printf("%lld",n)
#define speed ios_base::sync_with_stdio(0)
#define Max(a,b) a>b?a:b
#define Min(a,b) a<b?a:b
#define mem(n,x) memset(n,x,sizeof(n))
#define INF  0x3f3f3f3f
#define maxn  305
#define esp  1e-9
#define mp(a,b) make_pair(a,b)
using namespace std;
typedef long long ll;
//-----------------------*******----------------------------//
const int N=1000;
int n,m;//点数,边数,编号都从0开始
long long  w[N];//w[i]表示第i条边的权值(距离)
int u[N],v[N];//u[i]和v[i]分别表示第i条边的起点和终点
long long  dis[N];//单源最短路径
const long long  inf=(1LL<<60);
void ford(int s)
{
    for(int i=0;i<=n+2;i++)
        dis[i]=inf;
    dis[s]=0;
    for(int i=1;i<=n-1;i++)//枚举除终点外的所有点
        for(int j=1;j<=m;j++)//枚举所有边
        {
            int x=u[j];//边j的起点
            int y=v[j];//边j的终点
            if(dis[x]<inf)//松弛
                dis[y]=min(dis[y],dis[x]+w[j]);
        }
} //就是这个板子,难受的雅痞
int main()
{
   // cout<<inf;
    int T;
    cini(T);
    while(T--)
    {
        cini(n);
        cini(m);
        for(int i=1; i<=m; i++)
        {
            int x,y;
            long long z;
            cini(x),cini(y),cinl(z);
            u[i]=x;
            v[i]=y;
            w[i]=z;
        }
        for(int i=0;i<6;i++)
        {
            int x,y;
            cini(x),cini(y);
            ford(y);
            long long z=dis[x];
            u[++m]=x;
            v[m]=y;
            w[m]=-z;
            printf("%lld\n",-z);

        }
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-09-02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Input
  • Output
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档