P4878 [USACO05DEC]Layout G+P2294 [HNOI2005]狡猾的商人
Posted 钟钟终
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P4878 [USACO05DEC]Layout G+P2294 [HNOI2005]狡猾的商人相关的知识,希望对你有一定的参考价值。
P2294 [HNOI2005]狡猾的商人
分不清就多跑几轮,没必要去纠结n次还是n+1次松弛。
话说bellman-ford每个点被松弛n-1次
num[v]++;
if(num[v]>n)
return 0;
#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
const int inf=0x3f3f3f3f;
int n,m,head[maxn],cnt,dist[maxn],num[maxn];
bool vis[maxn];
struct node
int to,nxt,dis;
e[maxn];
void add(int u,int v,int w)
e[++cnt].to=v;
e[cnt].dis=w;
e[cnt].nxt=head[u];
head[u]=cnt;
bool spfa(int u)
queue<int>q;
memset(num,0,sizeof(num));
memset(vis,0,sizeof(vis));
memset(dist,inf,sizeof(dist));
dist[u]=0;
q.push(u);
vis[u]=1;
while(!q.empty())
int u=q.front();q.pop();
vis[u]=0;
for(int i=head[u];i;i=e[i].nxt)
int v=e[i].to;
if(dist[v]>dist[u]+e[i].dis)
dist[v]=dist[u]+e[i].dis;
num[v]++;
if(num[v]>n)
return 0;
if(!vis[v])
q.push(v);
vis[v]=1;
return 1;
signed main()
int t;cin>>t;
while(t--)
memset(head,0,sizeof(head));
cnt=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) //建立超级源点
add(n+1,i,0);
for(int i=1;i<=m;i++)
int a,b,c;scanf("%d%d%d",&a,&b,&c);
add(a-1,b,c);add(b,a-1,-c);
if(spfa(n+1))
cout<<"true"<<endl;
else
cout<<"false"<<endl;
return 0;
P4878 [USACO05DEC]Layout G
1.相邻牛建边,d[i]-d[i+1]<=0
,防止存在负权环。
2.建立超级源点,来判断图的连通性,距离为无穷大,或者存在负环就无解了。
#include <bits/stdc++.h>
using namespace std;
const int maxn=2e6+5;
const int inf=0x3f3f3f3f;
int n,m,h,head[maxn],cnt,dist[maxn],num[maxn];
bool vis[maxn];
struct node
int to,nxt,dis;
e[maxn];
void add(int u,int v,int w)
e[++cnt].to=v;
e[cnt].dis=w;
e[cnt].nxt=head[u];
head[u]=cnt;
queue<int>q;
void spfa(int u)
memset(num,0,sizeof(num));
memset(vis,0,sizeof(vis));
memset(dist,inf,sizeof(dist));
dist[u]=0;
q.push(u);
vis[u]=1;
num[u]=1;
while(!q.empty())
int u=q.front();q.pop();
vis[u]=0;
for(int i=head[u];i;i=e[i].nxt)
int v=e[i].to;
if(dist[v]>dist[u]+e[i].dis)
dist[v]=dist[u]+e[i].dis;
num[v]++;
if(num[u]==n)
cout<<"-1"<<endl;
exit(0);
if(!vis[v])
q.push(v);
vis[v]=1;
signed main()
scanf("%d%d%d",&n,&m,&h);
for(int i=1;i<=n;i++)
add(0,i,0);
for(int i=1;i<n;i++)
add(i+1,i,0);
for(int i=1;i<=m;i++)
int u,v,w;scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
for(int i=1;i<=h;i++)
int u,v,w;scanf("%d%d%d",&u,&v,&w);
add(v,u,-w);
spfa(0);
spfa(1);
if(dist[n]==inf)
cout<<"-2"<<endl;
else
cout<<dist[n]<<endl;
return 0;
以上是关于P4878 [USACO05DEC]Layout G+P2294 [HNOI2005]狡猾的商人的主要内容,如果未能解决你的问题,请参考以下文章