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]狡猾的商人的主要内容,如果未能解决你的问题,请参考以下文章

Luogu P4878 [USACO05DEC]布局

[USACO05DEC] 布局 [差分约束]

[Usaco2005 dec]Layout

bzoj 1731: [Usaco2005 dec]Layout 排队布局差分约束

P5194 [USACO05DEC]Scales 天平

Luogu6080 [USACO05DEC]Cow Patterns G