dijiskra重载运算符时我竟然把w>b.w写成w>b.to,调了2h,我哭了。
题意问能否通过时间隧道回溯到出发以前。
SPFA找负环。时间隧道回去的时间相当于一条负边。
1、注意时间隧道是单向边,我还找了半天。。。
2、图可以是不连通的。不能只spfa(1).
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <vector>
#define INF 0x3f3f3f3f
using namespace std;
const int N=5010;
struct node
{
int v,w;
node (int v,int w):v(v),w(w){}
};
vector<node>tr[N];
int dis[N],n;
bool spfa(int s)
{
int cnt[N];
bool vis[N];
memset(vis,0,sizeof(vis));
memset(cnt,0,sizeof(cnt));
queue<int>q;
while(!q.empty())
q.pop();
dis[s]=0;
vis[s]=1;
cnt[s]++;
q.push(s);
while(!q.empty())
{
int tmp=q.front();
q.pop();
vis[tmp]=0;
for(int i=0;i<tr[tmp].size();i++)
{
int v=tr[tmp][i].v;
if(dis[v]==-1||dis[v]>dis[tmp]+tr[tmp][i].w)
{
dis[v]=dis[tmp]+tr[tmp][i].w;
cnt[v]++;
if(cnt[v]>=n)
return true;
if(!vis[v])
{
vis[v]=1;
q.push(v);
}
}
}
}
return false;
}
int main()
{
int T,m,w,u,v,t;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&w);
for(int i=1;i<=n;i++)
tr[i].clear();
memset(dis,-1,sizeof(dis));
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&u,&v,&t);
tr[u].push_back(node(v,t));
tr[v].push_back(node(u,t));
}
for(int i=0;i<w;i++)
{
scanf("%d%d%d",&u,&v,&t);
tr[u].push_back(node(v,-t));
}
bool flag=1;
for(int i=1;i<=n&&flag;i++)
if(dis[i]==-1)//图不连通
if(spfa(i))
{
printf("YES\n");
flag=0;
}
if(flag)
printf("NO\n");
}
}
最短路裸题,dijiskra秒了。
在这之前看自己板子竟然觉得自己没有对dis初始化,后来发现是因为memset赋2147483647会变成-1,所以用循环的形式赋的值,一下子没看到。。。
#include <cstdio>
#include <queue>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#define INF 2147483647
using namespace std;
const int N=100010;
struct edge
{
int to,w;
edge (int _to,int _w):to(_to),w(_w){}
bool operator < (const edge &b) const
{
return w>b.w;
}
};
vector<edge>tr[N];
bool vis[N];
int dis[N];
void di(int n,int s)
{
memset(vis,0,sizeof(vis));
for(int i=0;i<=n;i++)//memset 10½øÖÆ´óÊý»á³ö´í
dis[i]=INF;
priority_queue<edge>q;
while(!q.empty())
q.pop();
dis[s]=0;
q.push(edge(s,0));
while(!q.empty())
{
edge tmp=q.top();
q.pop();
int u=tmp.to;
if(vis[u]) continue;
vis[u]=1;
for(int i=0;i<tr[u].size();i++)
{
int v=tr[u][i].to,w=tr[u][i].w;
if(!vis[v]&&dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
q.push(edge(v,dis[v]));
}
}
}
}
int main()
{
int t,n,u,v,w;
while(~scanf("%d%d",&t,&n))
{
for(int i=1;i<=n;i++)
tr[i].clear();
for(int i=0;i<t;i++)
{
scanf("%d%d%d",&u,&v,&w);
tr[u].push_back(edge(v,w));
tr[v].push_back(edge(u,w));
}
di(n,1);
printf("%d\n",dis[n]);
}
}