虫洞,很奇葩的名字。。。。题目描述跟奇葩。。。说有一些特殊的虫洞能穿越时空。。问能否看到出发前的自己。。
即判断是否存在负权回路问题
SPFA 跟 Bell_man 皆可。
SPFA队列算法
Bell_man 算法
即判断是否存在负权回路问题
SPFA 跟 Bell_man 皆可。
SPFA队列算法
#include <cstdio>
#include <cstring>
#include <queue>
const int fMax = 505,eMax = 5205,wMax = 0x3f3f3f3f;
using namespace std;
struct Edge
{
int v,dis,next;
}edge[eMax];
int head[fMax];
int k;
int field , path , hole;
int main()
{
void addedge(int s,int e,int t);
bool spfa();
int farm;
scanf("%d",&farm);
while(farm--)
{
k = 0;
memset(head,-1,sizeof(head));
scanf("%d %d %d",&field, &path , &hole);
int s,e,t,i;
for( i = 1 ; i <= path ; i++)
{
scanf("%d %d %d",&s,&e,&t);
addedge(s,e,t);
addedge(e,s,t);
}
for( i = 1 ; i <= hole ; i++)
{
scanf("%d %d %d",&s,&e,&t);
addedge(s,e,-t);
}
printf("%s\n",spfa()?"YES":"NO");
}
return 0;
}
void addedge(int s,int e,int t)
{
edge[k].v = e;
edge[k].dis = t;
edge[k].next = head[s];
head[s] = k++;
}
bool spfa()
{
int count[fMax];
queue<int>q;
bool vis[fMax];
int dis[fMax];
memset(vis,false,sizeof(vis));
memset(dis,0x3f,sizeof(dis));
memset(count,0,sizeof(count));
q.push(1);
dis[1] = 0;
while(!q.empty())
{
int x = q.front();
q.pop();
vis[x] = false;
for(int i = head[x] ; i != -1 ; i = edge[i].next)
{
int key = edge[i].v;
if(dis[key] > dis[x] + edge[i].dis)
{
dis[key] = dis[x] + edge[i].dis;
if(!vis[key])
{
q.push(key);
count[key]++;
vis[key] = true;
if(count[key]>field)
{
return true;
}
}
}
}
}
return false;
}
Bell_man 算法
#include<iostream>
using namespace std;
const int fMax = 505;
const int eMax = 5205;
const int wMax = 99999;
struct{
int sta, end, time;
}edge[eMax];
int point_num, edge_num, dict[fMax];
bool bellman_ford()
{
int i, j;
for(i = 2; i <= point_num; i ++)
dict[i] = wMax;
for(i = 1; i < point_num; i ++)
{
bool finish = true; // 加个全部完成松弛的判断,优化了50多MS。
for(j = 1; j <= edge_num; j ++)
{
int u = edge[j].sta;
int v = edge[j].end;
int w = edge[j].time;
if(dict[v] > dict[u] + w)
{ // 松弛。
dict[v] = dict[u] + w;
finish = false;
}
}
if(finish) break;
}
for(i = 1; i <= edge_num; i ++)
{ // 是否存在负环的判断。
int u = edge[i].sta;
int v = edge[i].end;
int w = edge[i].time;
if(dict[v] > dict[u] + w)
return false;
}
return true;
}
int main()
{
int farm;
scanf("%d", &farm);
while(farm --)
{
int field, path, hole;
scanf("%d %d %d", &field, &path, &hole);
int s, e, t, i, k = 0;
for(i = 1; i <= path; i ++)
{
scanf("%d %d %d", &s, &e, &t); // 用scanf代替了cin,优化了100多MS。
k ++;
edge[k].sta = s;
edge[k].end = e;
edge[k].time = t;
k ++;
edge[k].sta = e;
edge[k].end = s;
edge[k].time = t;
}
for(i = 1; i <= hole; i ++)
{
scanf("%d %d %d", &s, &e, &t);
k ++;
edge[k].sta = s;
edge[k].end = e;
edge[k].time = -t;
}
point_num = field;
edge_num = k;
if(!bellman_ford())
printf("YES\n");
else printf("NO\n");
}
return 0;
}