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;
    }

  • 相关阅读:
    方维P2P  二次开发
    Array 数组去重 总结10方法(7)
    PHP  OOP学习总结
    [转载]js:数组里面获取键名和键值
    Array对象的方法实现(6)----Array.prototype.indexOf(实现常规参数的功能)
    在Apache服务器上启用GZip压缩静态内容的方法
    PHP 程序授权验证开发思路
    【转】zend studio中ctrl+鼠标左键无法转到类或函数定义文件的解决方法
    公钥私钥,HTTPS,CA证书机构,单向和双向认证
    Array对象的方法实现(5)----Array.prototype.includes(实现常规参数的功能)
  • 原文地址:https://www.cnblogs.com/zzqc/p/6804493.html
Copyright © 2011-2022 走看看