POJ--3259--spfa spfa寫法
poj-3259
題目
While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way path that delivers you to its destination at a time that is BEFORE you entered the wormhole! Each of FJ’s farms comprises N (1 ≤ N ≤ 500) fields conveniently numbered 1..N, M (1 ≤ M ≤ 2500) paths, and W (1 ≤ W ≤ 200) wormholes.
As FJ is an avid time-traveling fan, he wants to do the following: start at some field, travel through some paths and wormholes, and return to the starting field a time before his initial departure. Perhaps he will be able to meet himself :) .
To help FJ find out whether this is possible or not, he will supply you with complete maps to F (1 ≤ F ≤ 5) of his farms. No paths will take longer than 10,000 seconds to travel and no wormhole can bring FJ back in time by more than 10,000 seconds.
Input
Line 1: A single integer, F. F farm descriptions follow.
Line 1 of each farm: Three space-separated integers respectively: N, M, and W
Lines 2.. M+1 of each farm: Three space-separated numbers ( S, E, T) that describe, respectively: a bidirectional path between S and E that requires T seconds to traverse. Two fields might be connected by more than one path.
Lines M+2.. M+ W+1 of each farm: Three space-separated numbers ( S, E, T) that describe, respectively: A one way path from S to E that also moves the traveler back T seconds.
Output
Lines 1.. F: For each farm, output “YES” if FJ can achieve his goal, otherwise output “NO” (do not include the quotes).
Sample Input
2
3 3 1
1 2 2
1 3 4
2 3 1
3 1 3
3 2 1
1 2 3
2 3 4
3 1 8
Sample Output
NO
YES
Hint
For farm 1, FJ cannot travel back in time.
For farm 2, FJ could travel back in time by the cycle 1->2->3->1, arriving back at his starting location 1 second before he leaves. He could start from anywhere on the cycle to accomplish this.
大意:就是有一個人有n個農場,農場與農場間共有M條路,長度為val,有的有蟲洞,從蟲洞過去後會回到val時間前,問你是否看到他自己
最短路,判負環,不用多說spfa
SPFA 判負環
bfs:判斷入隊次數是否超過頂點數
dfs: 判斷是否重複遞迴
鄰接矩陣
BFS 和SLF優化
SLF 優化:就是把佇列改成雙端佇列,再入隊前先判斷,如果隊首大於就放到隊尾,小於的話放到隊前。。。。。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<deque>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
int map[502][502];
int n,m,b;
void spfa()
{ int a[502]={0};
int vis[520]={0};
int dis[520];
memset(dis,INF,sizeof(dis));
vis[1]=1;
dis[1]=0;
deque<int>q;
q.push_front(1);
while(!q.empty())
{
int now=q.front();
q.pop_front();
vis[now]=0;
for(int i=1;i<=n;i++)
{
if(dis[i]>dis[now]+map[now][i])
{
dis[i]=dis[now]+map[now][i];
if(!vis[i])
{ a[i]++;
if(a[i]>=n)
{
printf("YES\n");return;
}
vis[i]=1;
if(!q.empty())
{
if(dis[i]>dis[q.front()])
{
q.push_back(i);
}
else
q.push_front(i);
}
else
q.push_front(i);
}
}
}
}
printf("NO\n");
}
int main()
{
std::ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--)
{
cin>>n>>m>>b;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j) map[i][j]=map[j][i]=0;
else map[i][j]=map[j][i]=INF;
}
}
for(int i=1;i<=m;i++)
{
int x,y,v;
cin>>x>>y>>v;
if(map[x][y]>v)
map[x][y]=map[y][x]=v;
}
for(int i=1;i<=b;i++)
{
int x,y,v;
cin>>x>>y>>v;
if(map[x][y]>-v)
map[x][y]=-v;
}
spfa();
}
return 0;
}
DFS (超時,不知道是不是這道題的問題)
//poj 3259
#include<iostream>
#include<cstring>
#include<cstdio>
#include<deque>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
int map[502][502];
int v[502]={0};
int n,m,b;
int flag=0;
int d[502]={0};
void spfa(int i)
{ if(flag) return;
v[i]=1;
for(int j=1;j<=n;j++)
{
if(d[j]>d[i]+map[i][j])
{
d[j]=d[i]+map[i][j];
if(v[j])
{
flag=1;return;
}
if(flag) return;
spfa(j);
}
}
v[i]=0;
}
int main()
{
std::ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--)
{
cin>>n>>m>>b;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j) map[i][j]=map[j][i]=0;
else map[i][j]=map[j][i]=INF;
}
}
for(int i=1;i<=m;i++)
{
int x,y,v;
cin>>x>>y>>v;
if(map[x][y]>v)
map[x][y]=map[y][x]=v;
}
for(int i=1;i<=b;i++)
{
int x,y,v;
cin>>x>>y>>v;
if(map[x][y]>-v)
map[x][y]=-v;
}
memset(v,0,sizeof(v));
memset(d,INF,sizeof(d));
d[1]=0;flag=0;
spfa(1);
if(flag)
cout<<"YES"<<endl;
else
{
cout<<"NO"<<endl;
}
}
return 0;
}
鄰接表
BFS
#include<cstring>
#include<cstdio>
#include<queue>
#define INF 0x3f3f3f3f
int m,n,w;
using namespace std;
int head[522];
int u; int dis[520];
struct sp
{
int v,va,next;
}q[5200];
bool spfa()
{
memset(dis,INF,sizeof(dis));
bool vis[520]={0};
int cur;
int cnt[520]={0};
vis[1]=true;
dis[1]=0;
cnt[1]=1;
queue<int>p;
p.push(1);
while(!p.empty())
{
cur=p.front();
p.pop();
vis[cur]=false;
for(int i=head[cur];i!=-1;i=q[i].next)
{
int id=q[i].v;
if(dis[cur]+q[i].va<dis[id])
{
dis[id]=dis[cur]+q[i].va;
if(!vis[id])
{
cnt[id]++;
vis[id]=true;
p.push(id);
if(cnt[id]>n)
{
return true;
}
}
}
}
}
return false;
}
void add(int x,int y,int z)
{
q[u].v=y;
q[u].va=z;
q[u].next=head[x];
head[x]=u++;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{ u=0;
memset(head,-1,sizeof(head));
scanf("%d%d%d",&m,&n,&w);
for(int j=0;j<n;j++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
for(int i=0;i<w;i++)
{
int a,b,va;
scanf("%d%d%d",&a,&b,&va);
add(a,b,-va);
}
if(spfa())
{ printf("YES\n");
}
else
printf("NO\n");
}
return 0;
}
dfs
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int n,m,w,o;
#define INF 0x3f3f3f3f
struct pp
{
int v,va,next;
}ss[5200];
int head[520];
int vis[520];
int dis[520];
void add(int u,int v,int val)
{
ss[o].v=v;
ss[o].va=val;
ss[o].next=head[u];
head[u]=o++;
}
int flag=0;
void spfa(int x)
{ if(flag) return;
vis[x]=1;
for(int i=head[x];i!=-1;i=ss[i].next)
{ int v=ss[i].v;int val=ss[i].va;
if(dis[v]>val+dis[x])
{
dis[v]=val+dis[x];
if(vis[v])
{
flag=1;
return;
}
spfa(v);
if(flag) return;
}
}
vis[x]=0;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{ o=0;
memset(head,-1,sizeof(head));
scanf("%d%d%d",&n,&m,&w);
for(int i=0;i<m;i++)
{
int u,v,val;
scanf("%d%d%d",&u,&v,&val);
add(u,v,val);
add(v,u,val);
}
for(int i=0;i<w;i++)
{
int u,v,val;
scanf("%d%d%d",&u,&v,&val);
add(u,v,-val);
}
memset(dis,INF,sizeof(dis));
dis[1]=0;
flag=0;
memset(vis,0,sizeof(vis));
spfa(1);
if(flag)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
vector
和鄰接表類似,只不過換用存法了
BFS
#include<cstring>
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#define INF 0x3f3f3f3f
int m,n,w;
using namespace std;
struct pp
{
int v,va;
}ss;
vector<pp>qq[5200];
void spfa()
{
int dis[520];
memset(dis,INF,sizeof(dis)) ;
int vis[520]={0};
dis[1]=0;
vis[1]=1;
int cnt[520]={0};
queue<int>q1;
q1.push(1);
cnt[1]=1;
while(!q1.empty())
{
int now=q1.front();
q1.pop();
vis[now]=0;
int len=qq[now].size();
for(int i=0;i<len;i++)
{ int v=qq[now][i].v;int va=qq[now][i].va;
if(dis[v]>va+dis[now])
{
dis[v]=va+dis[now];
if(!vis[v])
{
cnt[v]++;
q1.push(v);
vis[v]=1;
if(cnt[v]>=m)
{
printf("YES\n");
return;
}
}
}
}
}
printf("NO\n");
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&m,&n,&w);
for(int i=0;i<m+10;i++)
qq[i].clear();
for(int i=0;i<n;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
ss.v=y;ss.va=z;
qq[x].push_back(ss);
ss.v=x;
qq[y].push_back(ss);
}
for(int j=0;j<w;j++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
ss.v=y;ss.va=-z;
qq[x].push_back(ss);
}
spfa();
}
return 0;
}
DFS
#include<cstring>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
int n,m,w,o;
#define INF 0x3f3f3f3f
struct pp
{
int v,val;
}ss;
int flag=1;
int dis[520],vis[520];
vector<pp>q[520];
void spfa( int x)
{ if(flag) return;
vis[x]=1;
int len=q[x].size();
for(int i=0;i<len;i++)
{
int v=q[x][i].v;
int val=q[x][i].val;
if(dis[v]>dis[x]+val)
{
dis[v]=dis[x]+val;
if(vis[v])
{
flag=1;
return;
}
spfa(v);
if(flag) return;
}
}
vis[x]=0;
}
int main()
{
// ios::sync_with_stdio(false);
int t;
// cin>>t;
scanf("%d",&t);
while(t--)
{
cin>>n>>m>>w;
for(int i=1;i<=n;i++)
q[i].clear();
for(int i=0;i<m;i++)
{ int u,v;
// cin>>u>>v>>ss.val;
scanf("%d%d%d",&u,&v,&ss.val);
ss.v=u;
q[v].push_back(ss);
ss.v=v;
q[u].push_back(ss);
}
for(int i=0;i<w;i++)
{ int u,v,val;
// cin>>u>>v>>val;
scanf("%d%d%d",&u,&v,&val);
ss.v=v;ss.val=-val;
q[u].push_back(ss);
}
memset(vis,0,sizeof(vis));
memset(dis,INF,sizeof(dis));
dis[1]=0;
flag=0;
spfa(1);
if(flag) printf("YES\n");
else printf("NO\n");
}
return 0;
}
vector真是個好東西!
還有這道題cin輸出取消同步後比printf多300ms。
學習。。。。。