• zoj 2770(差分约束)


    设a[i] 为第i个营的人数,s[i] = a[1] + a[2] + … + a[i], s[0] = 0

           则对于题目

           Ci 有: 0 <= s[i] – s[i-1] <= a[i]  -----(1)

           i, j, k有:a[i]+a[i+1]+...a[j]>= s[j] – s[i-1] >= k   -----(2)

           化为以下四个式子:

    s[i]-s[i-1]<=a[i]  ------>addedge(i-1,i,a[i])

    s[i-1]-s[i]<=0 --------->addedge(i,i-1,0)

    s[j]-s[i-1]<=sum[j]-sum[i-1]----->addedge(i-1,j,sum[j]-sum[i-1])

    s[i-1]-s[j]<=-k  ---->addedge(j,i-1,-k)

    设答案为ans.则显然s[n]-s[0]>=ans  ---->s[0]-s[n]<=-ans;

    相当于从n-->0的边权值为-ans。

    故可以从n为源点求最短路.

    另外:用vector来存邻接表貌似很方便。。

     1 // File Name: 2770.cpp
     2 // Author: Missa
     3 // Created Time: 2013/2/20 星期三 12:22:46
     4 
     5 #include<iostream>
     6 #include<cstdio>
     7 #include<cstring>
     8 #include<algorithm>
     9 #include<cmath>
    10 #include<queue>
    11 #include<stack>
    12 #include<string>
    13 #include<vector>
    14 #include<cstdlib>
    15 #include<map>
    16 #include<set>
    17 using namespace std;
    18 #define CL(x,v) memset(x,v,sizeof(x));
    19 const int inf = 0x3f3f3f3f;
    20 const int maxm = 2e5+5;
    21 const int maxn = 1005;
    22 int n,m;
    23 struct edge
    24 {
    25     int v;
    26     int c;
    27     edge(){}
    28     edge(int v,int c):v(v),c(c){}
    29 };
    30 vector<edge>e[maxn];
    31 int a[maxn],sum[maxn],dis[maxn],cnt[maxn];
    32 void addedge(int u,int v,int c)
    33 {
    34     e[u].push_back(edge(v,c));
    35 }
    36 bool relax(int u,int v,int c)
    37 {
    38     if(dis[v]>dis[u]+c)
    39     {
    40         dis[v]=dis[u]+c;
    41         return true;
    42     }
    43     return false;
    44 }
    45 bool spfa(int src)
    46 {
    47     bool vis[maxn];CL(vis,0);
    48     CL(dis,0x3f);
    49     dis[src]=0;vis[src]=1;
    50     queue<int>q;q.push(src);
    51     while(!q.empty())
    52     {
    53         int pre=q.front();q.pop();
    54         vis[pre]=0;
    55         for(int i=0;i<e[pre].size();i++)
    56         {
    57             if(relax(pre,e[pre][i].v,e[pre][i].c) && !vis[e[pre][i].v])
    58             {
    59                 if((++cnt[e[pre][i].v]) > n) return false;
    60                 q.push(e[pre][i].v);
    61                 vis[e[pre][i].v]=1;
    62             }
    63         }
    64     }
    65     return true;
    66 }
    67 int main()
    68 {
    69     while(~scanf("%d%d",&n,&m))
    70     {
    71         CL(a,0);
    72         CL(sum,0);
    73         CL(cnt,0);
    74         CL(e,0);
    75         int u,v,c;
    76         for(int i=1;i<=n;i++)
    77         {
    78             scanf("%d",&a[i]);
    79             sum[i]=sum[i-1]+a[i];
    80         }
    81         for(int i=1;i<=m;i++)
    82         {
    83             scanf("%d%d%d",&u,&v,&c);
    84             addedge(v,u-1,-c);
    85             addedge(u-1,v,sum[v]-sum[u-1]);
    86         }
    87         for(int i=1;i<=n;i++)
    88         {
    89             addedge(i,i-1,0);
    90             addedge(i-1,i,a[i]);
    91         }
    92         if(!spfa(n)) puts("Bad Estimations");
    93         else
    94             printf("%d\n",dis[n]-dis[0]);
    95     }
    96     return 0;
    97 }
  • 相关阅读:
    C#日期加减
    c#的预编译指令
    IHttpModule与IHttpHandler的区别整理
    ASP.NET提供程序
    在所有页面共享通用行为
    5.Oracle中的数据表
    asp.net跳转页面的三种方法比较(转)
    C#实现经典排序算法
    ASP.NET用户登录模块代码
    http错误锦集
  • 原文地址:https://www.cnblogs.com/Missa/p/2918655.html
Copyright © 2020-2023  润新知