Date:2019/11/1
坑点
- 输出
- 板子的写法
- 数组要初始化!!!!!
多组输入:数组不清零,爆零两行泪 - 每组数据建边的时候,tot|cnt要从0开始
只有负数建单向边,0建双向边 - spfa的结尾要return false即为不是负环
AC code
#include<bits/stdc++.h>
using namespace std;
#define maxn 10000
int n,m,s,cnt;
int hd[maxn], dis[2*maxn];
//hd[]--记边 dis[]--计最短路
int vis[2*maxn], ji[2*maxn];
//vis[]--标记数组 ji[]--记走了几步
struct Edge{
int to,nxt,w;
}edge[2*maxn]; //边的储存
void add(int u,int v,int w){ //建边
cnt++;
edge[cnt].to = v;
edge[cnt].w = w;
edge[cnt].nxt = hd[u];
hd[u] = cnt;
}
//----------------------------------------------------------
bool spfa(){
queue <int> q;
q.push(1); dis[1] =0;ji[1]=1;vis[1] = 1;
while(!q.empty()){
int u = q.front(); //取出队首
q.pop(); //弹出队首
vis[u] = false; //队首还原(可以再次入队
for(int j = hd[u]; j!=-1;j = edge[j].nxt){//##这里不要写错!!
int v = edge[j].to; //找儿子
if(dis[v] > dis[u] + edge[j].w){
dis[v] = dis[u] + edge[j].w;//三角形的松弛操作
ji[v] = ji[u] + 1; //入队次数记录
if(ji[v] > n){ //超了跳出
return true;
}
if(!vis[v]){ //如果没有遍历过
vis[v] = true; //打标记
q.push(v); //推入队列里
}
}
}
}
return false;//这里要注意~~
}
int main(){
// freopen("1.in","r",stdin);
// freopen("1.out","w",stdout); //提交时候不要写这个!!!
int T;
scanf("%d",&T);
while(T--){
cnt = 0; //统计的数组初始化
scanf("%d %d",&n,&m);
for(int i = 1;i <= n+5 ;i++){
hd[i]=-1; //建立边的数组初始化
dis[i]=0x3f3f3f3f; //距离数组初始化 (注意和 memset(dis,0x3f,sizeof(dis)) 的区别
vis[i]=0; //标记数组初始化
ji[i]=0; //判定负环数组初始化
}
for(int i = 1,fi,gi,wi; i <= m; i++){
scanf("%d %d %d",&fi,&gi,&wi);
add(fi,gi,wi);
if(wi>=0) add(gi,fi,wi);//这里是题目要求,双向
}
if(spfa()) printf("YE5\n");
else printf("N0\n"); //恶心心的输出
}
return 0;
}
KaTeX parse error: Undefined control sequence: \font at position 16: \to \color{red}\̲f̲o̲n̲t̲{Happy \:ending