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
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
题意:初始给定你一个图,这个图中的边有正值有负值,但是一定保证图没有负环,现在让你依次添加6条边,每条边的值都尽可能小,小到可能为负值,但是一定得保证添加后图中不会产生负环,找到对应值后加入图中,在这个基础上继续找下一条边。
题解:很明显的用二分查找判断负环,因为写spfa的习惯,一开始直接用了很复杂的spfa来判断负环。
AC代码
#include
using namespace std;
const int N=20100;
typedef long long ll;
struct Node{
int v,next;
ll w;
}edge[N];
int head[N],cnt;
void add_edge(int u,int v,ll w)
{
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt++;
}
//inqt为判断某个点被松弛的次数
int inqt[N],n,m;
queueq;
ll dis[N];
bool vis[N];
bool spfa()
{
for(int i=0;i<=n;i++)
dis[i]=1e14,vis[i]=false,inqt[i]=0;
while(!q.empty())
q.pop();
dis[0]=0;
q.push(0);
inqt[0]=1;
vis[0]=true;
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=false;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
ll w=edge[i].w;
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
if(!vis[v])
{
vis[v]=true;
inqt[v]++;
q.push(v);
//说明存在负环
if(inqt[v]>n)
{
return false;
}
}
}
}
}
return true;
}
struct Code
{
int u,v;
ll w;
};
vectorct;
bool check(Code t)
{
memset(head,-1,sizeof(head));
cnt=0;
for(int i=0;i
后来又发现自己写麻烦了,直接简单的Bellman-ford直接判断就行,改进后的超级简便的代码
AC代码
#include
#include
#include
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
struct V{
int u,v;
ll w;
}edge[600];
ll dis[600];
int n,m;
bool bellman_ford(){
memset(dis,INF,sizeof(dis));
for(int i=1;idis[edge[j].u]+edge[j].w){
dis[edge[j].v]=dis[edge[j].u]+edge[j].w;
}
}
}
for(int j=1;j<=m;++j){
if(dis[edge[j].v]>dis[edge[j].u]+edge[j].w)
return false;
}
return true;
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n>>m;
for(int i=1;i<=m;i++)
cin>>edge[i].u>>edge[i].v>>edge[i].w;
int ans=6;
while(ans--)
{
m++;
cin>>edge[m].u>>edge[m].v;
ll l=-1e16,r=1e16;
ll res;
while(l<=r)
{
ll mid=(l+r)/2;
edge[m].w=mid;
if(bellman_ford())
{
res=mid;
r=mid-1;
}
else l=mid+1;
}
edge[m].w=res;
cout<