zoukankan      html  css  js  c++  java
  • 【题解】 [HNOI2005]狡猾的商人(差分约束)

    题面懒得复制,戳我戳我

    Solution:

    • 其实这个差分是挺显然的,我们可以用(s[i])表示从第(1)(i)中间的收入和
    • 重点就在式子,比如读入(a),(b),(c),显然可以得到一个式子:$$s[b]-s[a-1]==c$$把这个式子变成不等式就是$$s[b]>=c+s[a-1]$$$$s[b]>=c+s[a-1]$$第二个式子又可以转换成$$s[a-1]<=-c+s[b]$$这就显然是从(a-1)连向(b)一条长度为(c)的边,从(b)连向(a-1)一条(-c)的边
    • 然后我们就可以跑(SPFA)了,这有一点就是,因为要满足所有条件,每天的收入是固定的,我们就只用如下操作:更新至的点如果为(INF)(初值),就更新,否则判断是否符合边的条件要求(s[v]==s[u]+dis[u,v])(u为出发点,v为到达点)
    • 我傻逼的没有清空(vis)数组,WA了无数次(太愚蠢了)

    BTW:这题还可以用并查集,可以去思考丢个链接吧,Awson太强辣


    Code:

    //It is coded by Ning_Mew on 3.29
    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn=1000+10;
    
    int T,n,m,INF;
    int head[maxn],cnt=0,dist[maxn];
    bool be[maxn];
    struct Edge{int nxt,to,dis;}edge[maxn*2];
    
    void add(int from,int to,int dis){
      edge[++cnt].nxt=head[from];
      edge[cnt].to=to;
      edge[cnt].dis=dis;
      head[from]=cnt;
    }
    int vis[maxn];
    bool SPFA(int k,int ls){
      queue<int>Q;while(!Q.empty())Q.pop();
      vis[k]=ls;Q.push(k);be[k]=false;
      dist[k]=0;
      while(!Q.empty()){
        int u=Q.front();Q.pop();vis[u]=ls-1;
        for(int i=head[u];i!=0;i=edge[i].nxt){
          int v=edge[i].to;be[v]=false;
          if(dist[v]==INF){
            dist[v]=dist[u]+edge[i].dis;
            if(vis[v]!=ls){
              Q.push(v);
              vis[v]=ls;
            }
          }
          else{
       		if(dist[v]!=dist[u]+edge[i].dis)return false;
          }
        }
      }return true;
    }
    void work(){
      scanf("%d%d",&n,&m);
      memset(head,0,sizeof(head));
      memset(be,false,sizeof(be));cnt=0;
      memset(vis,0,sizeof(vis));
      for(int i=1;i<=m;i++){
        int a,b,c;scanf("%d%d%d",&a,&b,&c);
        add(a-1,b,c);be[a-1]=true;be[b]=true;
        	add(b,a-1,-1*c);
      }
      memset(dist,-0x5f,sizeof(dist));
      INF=dist[0];
      int ls=1;
      for(int i=0;i<=n;i++){
        if(be[i]==false)continue;
        //cout<<i<<endl;
        if(SPFA(i,++ls));else{
          printf("false
    ");
          return;
        }
      }printf("true
    ");
    }
    int main(){
      scanf("%d",&T);
      for(int i=1;i<=T;i++){work();}  
      return 0;
    }
    
    
  • 相关阅读:
    迈瑞医疗招聘-软件测试工程师
    软件自动化测试开发-3期开班啦
    luogu P2744 [USACO5.3]量取牛奶Milk Measuring
    luogu P2515 [HAOI2010]软件安装
    luogu P2423 双塔
    luogu P1651 塔
    luogu P1489 猫狗大战
    luogu P3092 [USACO13NOV]没有找零No Change
    luogu P3800 Power收集
    luogu P2949 [USACO09OPEN]工作调度Work Scheduling
  • 原文地址:https://www.cnblogs.com/Ning-Mew/p/8689075.html
Copyright © 2011-2022 走看看