zoukankan      html  css  js  c++  java
  • ZOJ 2770 差分约束+SPFA

    Burn the Linked Camp

    Time Limit: 2 Seconds      Memory Limit: 65536 KB

    It is well known that, in the period of The Three Empires, Liu Bei, the emperor of the Shu Empire, was defeated by Lu Xun, a general of the Wu Empire. The defeat was due to Liu Bei's wrong decision that he divided his large troops into a number of camps, each of which had a group of armies, and located them in a line. This was the so-called "Linked Camps".

    Let's go back to that time. Lu Xun had sent many scouts to obtain the information about his enemy. From his scouts, he knew that Liu Bei had divided his troops into n camps, all of which located in a line, labeled by 1..n from left to right. The ith camp had a maximum capacity of Ci soldiers. Furthermore, by observing the activities Liu Bei's troops had been doing those days, Lu Xun could estimate the least total number of soldiers that were lived in from the ith to the jth camp. Finally, Lu Xun must estimate at least how many soldiers did Liu Bei had, so that he could decide how many troops he should send to burn Liu Bei's Linked Camps.

    Input:

    There are multiple test cases! On the first line of each test case, there are two integers n (0<n<=1,000) and m (0<=m<=10,000). On the second line, there are n integers C1��Cn. Then m lines follow, each line has three integers i, j, k (0<i<=j<=n, 0<=k<2^31), meaning that the total number of soldiers from the ith camp to the jth camp is at least k.

    Output:

    For each test case, output one integer in a single line: the least number of all soldiers in Liu Bei's army from Lu Xun's observation. However, Lu Xun's estimations given in the input data may be very unprecise. If his estimations cannot be true, output "Bad Estimations" in a single line instead.

    Sample Input:

    3 2
    1000 2000 1000
    1 2 1100
    2 3 1300
    3 1
    100 200 300
    2 3 600
    

    Sample Output:

    1300
    Bad Estimations
    题意:给出n个点表示n个军营,c[i]表示第i个军营可容纳的士兵的最大值,接着给出m条边(i,j,k)表示从第i到第j个军营最少有的的士兵数。求在满足以上条件下最少有多少士兵!
    我们不妨设S(i)表示从第一个兵营到第i个兵营最少的士兵数,保存在d[i]中
    接着就是找出所有的不等式组。
    1.(i,j,k) --> S(j)-S(i-1)>=k 即S(i-1)-S(j)<=-k
    2.S(j)-S(i-1)<=c=d[j]-d[i-1];
    3.设A(i)表示每个军营的实际人数,显然 0<=A(i)<=c[i]
    即 S(i)-S(i-1)>=0&&S(i)-S(i-1)<=c[i];
    接着将不等式转化为边存入图中
    我们令 S(u)<=S(v)+w 表示连接一条从v到u且权值为w的有向边.

    #include<bits/stdc++.h>
    using namespace std;
    #define inf 0x3f3f3f3f
    inline int read()
    {
    int s=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') {s=s*10+ch-'0';ch=getchar();}
    return s*f;
    }
    struct Edge
    {
    int to;
    int w;
    int next;
    }edges[50005];
    int cnt,dis[10005];
    int first[10005];
    int n,m;
    bool vis[10005];
    int counts[10005];
    int c[10005];
    void add(int a,int b,int c)
    {
    //cout<<a<<" "<<b<<" "<<c<<endl;
    edges[cnt].to=b;
    edges[cnt].w=c;
    edges[cnt].next=first[a];
    first[a]=cnt++;
    }
    bool spfa(int st,int ed)
    {
    queue<int>Q;
    dis[st]=0;
    vis[st]=1;
    counts[st]++;
    Q.push(st);
    while(!Q.empty()){
    int u=Q.front();Q.pop();
    vis[u]=0;
    if(counts[u]>n) return false;
    for(int i=first[u];i+1;i=edges[i].next){
    int v=edges[i].to;
    if(dis[v]>dis[u]+edges[i].w){
    dis[v]=dis[u]+edges[i].w;
    if(!vis[v]) {Q.push(v);vis[v]=1;counts[v]++;}
    }
    }
    }
    //for(int i=1;i<=n;++i) cout<<dis[i]<<" ";cout<<endl;
    cout<<-dis[0]<<endl;
    return true;
    }
    int main()
    {
    int t,i,j;
    //cin>>t;
    while(cin>>n>>m){
    memset(first,-1,sizeof(first));
    memset(vis,0,sizeof(vis));
    memset(dis,inf,sizeof(dis));
    memset(counts,0,sizeof(counts));
    cnt=0;c[0]=0;

    for(i=1;i<=n;++i) {c[i]=read();
    add(i,i-1,0);
    add(i-1,i,c[i]);
    c[i]+=c[i-1];
    }
    int u,v,w;
    for(i=1;i<=m;++i)
    {
    u=read(),v=read(),w=read();
    add(v,u-1,-w);
    add(u-1,v,c[v]-c[u-1]);
    }

    if(!spfa(n,0)) puts("Bad Estimations");
    }
    return 0;
    }

  • 相关阅读:
    Python的优点和缺点
    如何在sed中使用变量方法及其简单
    shell脚本练习,创建数据文件注册用户并将用户信息存入文件内,用于模拟登录时使用
    shell脚本常用参数与格式
    运维方向和运维需要掌握的基本面
    linux系统awk命令精解
    数组去重方式
    原生js封装cookie获取、设置及删除
    sublime 浏览器快捷键设置
    background-image实现border效果及多图png如何实现background-size为原图一半
  • 原文地址:https://www.cnblogs.com/zzqc/p/6804493.html
Copyright © 2011-2022 走看看