• 洛谷 P5960 【模板】差分约束算法(差分约束)


    题目链接:https://www.luogu.com.cn/problem/P5960

    题目中x1-x'1<=y1可以转变为

        x1<=x'1+y1

    换一下字母更显然易见:dis[v]<=dis[u]+edge[i].w

    那么便可以转换成图上的最短路问题(解集),因为题中并没有说明是联通图,可以设一个超级源点,然后向每个节点连一条边权为0的边,然后从0点开始做最短路。

    注意建边是从x'1连向x1。

    AC代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<queue>
     5 using namespace std;
     6 int n,m,tot;
     7 const int N=5005;
     8 struct node{
     9     int to,next,w;
    10 }edge[N<<1];
    11 int head[N],dis[N],vis[N],in[N];
    12 void add(int u,int v,int w){
    13     edge[tot].to=v;
    14     edge[tot].next=head[u];
    15     edge[tot].w=w;
    16     head[u]=tot++;
    17 } 
    18 bool spfa(int u){
    19     queue<int> q;
    20     q.push(u);vis[u]=1;dis[u]=0;
    21     while(!q.empty()){
    22         u=q.front();q.pop();vis[u]=0;
    23         if(in[u]==n) return 0;
    24         for(int i=head[u];i!=-1;i=edge[i].next){
    25             int v=edge[i].to;
    26             if(dis[v]>=dis[u]+edge[i].w){
    27                 dis[v]=dis[u]+edge[i].w;
    28                 in[v]++;
    29                 if(!vis[v]){q.push(v);vis[v]=1;}
    30             }
    31         }
    32     }
    33     return 1;
    34 }
    35 int main(){
    36     memset(head,-1,sizeof(head));
    37     memset(dis,0x3f3f,sizeof(dis));
    38     scanf("%d%d",&n,&m);
    39     for(int i=1;i<=m;i++){
    40         int u,v,w;
    41         scanf("%d%d%d",&u,&v,&w);
    42         add(v,u,w);
    43     }
    44     for(int i=1;i<=n;i++) add(0,i,0);
    45     if(spfa(0)==0){printf("NO"); return 0;}
    46     for(int i=1;i<=n;i++) printf("%d ",dis[i]);
    47     return 0;
    48 }
    AC代码
  • 相关阅读:
    C语言扩展题
    C语言第五题
    C语言第四题
    C语言第三题
    c语言第二题
    11
    游戏开发的一些想法
    openxml的视频教程
    JavaScript调试之console.log
    IPPatternConverter
  • 原文地址:https://www.cnblogs.com/New-ljx/p/13411672.html
Copyright © 2020-2023  润新知