题意:
有虫洞可以时间回溯,从x,到y, 有土地可以从x,到y花费w时间。
询问是否可以从某点进去的时间在从这个点出来的时间之后
思路:
判负环
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stdio.h>
using namespace std;
#define maxn 100000
#define inf 0x3f3f3f3f
struct node
{
int from,to,val,next;
}edge[maxn];
int dist[maxn];
int vis[maxn];
int head[maxn];
int cnt[maxn];
int n,m,w;
int len=0;
void add(int u,int v, int w)
{
edge[++len].to=v;
edge[len].val=w;
edge[len].next=head[u];
head[u]=len;
}
int spfa()
{
queue <int > q;
for(int i=1;i<=n;i++)
dist[i]=inf,vis[i]=0,cnt[i]=0;
int cur=1;
q.push(cur);
vis[cur]=1;
cnt[cur]=1;
dist[cur]=0;
while(!q.empty())
{
cur=q.front();
q.pop();
vis[cur]=0;
for(int i=head[cur];i!=-1;i=edge[i].next)
{
int id=edge[i].to;
if(dist[id]>dist[cur]+edge[i].val )
{
dist[id]=dist[cur]+edge[i].val;
if(!vis[id])
{
cnt[id]++;
vis[id]=1;
q.push(id);
if(cnt[cur]>n)
return 1;
}
}
}
}
return 0;
}
int main()
{
int T;
cin>>T;
while(T--)
{
memset(head,-1,sizeof(head));
scanf("%d%d%d",&n,&m,&w);
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
for(int i=1;i<=w;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,-z);
}
if(spfa())
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
}
亲测:stack+spfa比queue deque都好用
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stdio.h>
using namespace std;
#define maxn 100000
#define inf 0x3f3f3f3f
struct node
{
int from,to,val,next;
}edge[maxn];
int dist[maxn];
int vis[maxn];
int head[maxn];
int cnt[maxn];
int n,m,w;
int len=0;
void add(int u,int v, int w)
{
edge[++len].to=v;
edge[len].val=w;
edge[len].next=head[u];
head[u]=len;
}
int Q[maxn];//堆栈
int spfa(int start,int n)
{
int top=0;
for(int v=1;v<=n;v++)//初始化
{
if(v==start)
{
Q[top++]=v;
vis[v]=true;
dist[v]=0;
}
else
{
vis[v]=false;
dist[v]=inf;
}
}
cnt[start]=1;
while(top!=0)
{
int u=Q[--top];
vis[u]=false;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(dist[v]>dist[u]+edge[i].val)
{
dist[v]=dist[u]+edge[i].val;
if(!vis[v])
{
vis[v]=true;
Q[top++]=v;
cnt[v]++;
if(cnt[v]>n)
return 1;
}
}
}
}
return 0;
}
int main()
{
int T;
cin>>T;
while(T--)
{
memset(Q,0,sizeof(Q));
memset(head,-1,sizeof(head));
memset(cnt,0,sizeof(cnt));
scanf("%d%d%d",&n,&m,&w);
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
for(int i=1;i<=w;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,-z);
}
if(spfa(1,n))
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
}