UVALive 4863 Balloons 贪心/费用流

 

There will be several test cases in the input. Each test case will begin with a line with three integers:


N A B


Where N is the number of teams (1$ \le$N$ \le$1, 000), and A and B are the number of balloons in rooms A and B, respectively (0$ \le$A, B$ \le$10, 000). On each of the next N lines there will be three integers, representing information for each team:


K DA DB


Where K is the total number of balloons that this team will need, DA is the distance of this team from room A, and DB is this team's distance from room B (0$ \le$DA, DB$ \le$1, 000). You may assume that there are enough balloons - that is, $ \sum$(K's)$ \le$A + B. The input will end with a line with three 0s.

Output

For each test case, output a single integer, representing the minimum total distance that must be traveled to deliver all of the balloons. Count only the outbound trip, from room A or room B to the team. Don't count the distance that a runner must travel to return to room A or room B. Print each integer on its own line with no spaces. Do not print any blank lines between answers.

Sample Input

3 15 35 

10 20 10 

10 10 30 

10 40 10 

0 0 0

Sample Output

300

 

 

费用流代码:

#include <cstdio>

#include <cstring>

using namespace std;



#define MAXN 2000

#define MAXM 4000

#define INF 0x3f3f3f3f

#define MIN(a,b) (a<b?a:b)

#define V(p) edge[(p)].v

#define F(p) edge[(p)].f

#define C(p) edge[(p)].c

#define Nx(p) edge[(p)].next



int n,A,B,s,t,ans,ecnt;

int dis[MAXN],adj[MAXN];

bool vis[MAXN];

struct node

{

    int v,f,c,next;

}edge[MAXM*2];



void Addedge(int u,int v,int f,int c)

{

    ++ecnt;

    V(ecnt)=v; F(ecnt)=f; C(ecnt)=c;

    Nx(ecnt)=adj[u]; adj[u]=ecnt;

    ++ecnt;

    V(ecnt)=u; F(ecnt)=0; C(ecnt)=-c;

    Nx(ecnt)=adj[v]; adj[v]=ecnt;

}



int Aug(int u,int lim)

{

    if(u==t){

        ans+=lim*dis[s];

        return lim;

    }

    vis[u]=true;

    int p,v,f,c,delta,sum=0;

    for(p=adj[u];p;p=Nx(p)){

        v=V(p); f=F(p); c=C(p);

        if(vis[v] || !f || dis[v]+c!=dis[u]) continue;

        delta=Aug(v,MIN(f,(lim-sum)));

        F(p)-=delta; F(p^1)+=delta;

        sum+=delta;

        if(sum==lim) break;

    }

    return sum;

}

bool Update()

{

    int i,p,Min=INF;

    for(i=s;i<=t;++i){

        if(!vis[i]) continue;

        for(p=adj[i];p;p=Nx(p)){

            if(!F(p) || vis[V(p)]) continue;

            Min=MIN(Min,(dis[V(p)]+C(p)-dis[i]));

        }

    }

    if(Min==INF) return false;

    for(i=s;i<=t;++i){

        if(!vis[i]) continue;

        dis[i]+=Min;

    }

    return true;

}

void ZKW()

{

    do{

        for(memset(vis,0,sizeof(vis));Aug(s,INF);memset(vis,0,sizeof(vis)));

    }while(Update());

    printf("%d\n",ans);

}



void Init()

{

    memset(adj,0,sizeof(adj));

    memset(dis,0,sizeof(dis));

    ans=0; ecnt=1; s=0; t=n+3;

    int i,k,da,db;

    Addedge(s,n+1,A,0);

    Addedge(s,n+2,B,0);

    for(i=1;i<=n;++i){

        scanf("%d%d%d",&k,&da,&db);

        Addedge(n+1,i,INF,da);

        Addedge(n+2,i,INF,db);

        Addedge(i,t,k,0);

    }

}

int main()

{

    while(true){

        scanf("%d%d%d",&n,&A,&B);

        if(!n && !A && !B) break;

        Init();

        ZKW();

    }

    return 0;

}

贪心代码:

#include <cstdio>

#include <cmath>

#include <cstring>

#include <ctime>

#include <iostream>

#include <algorithm>

#include <set>

#include <vector>

#include <sstream>

#include <queue>

#include <typeinfo>

#include <fstream>

typedef long long ll;

using namespace std;

//freopen("D.in","r",stdin);

//freopen("D.out","w",stdout);

#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)

#define maxn 10011

const int inf=0x7fffffff;   //无限大

struct node

{

    int total;

    int da;

    int db;

    int dis;

};

bool cmp(node a,node b)

{

    return a.dis>b.dis;

}

node team[maxn];

int    main()

{

    sspeed;

    int n,a,b;

    while(cin>>n>>a>>b)

    {

        if(n==0&&a==0&&b==0)

            break;

        int sum=0;

        for(int i=0;i<n;i++)

        {

            cin>>team[i].total>>team[i].da>>team[i].db;

            team[i].dis=fabs(team[i].da-team[i].db);

        }

        sort(team,team+n,cmp);

        for(int i=0;i<n;i++)

        {

            if(team[i].da<team[i].db)

            {

                if(a>=team[i].total)

                {

                    sum+=team[i].da*team[i].total;

                    a-=team[i].total;

                }

                else

                {

                    sum+=team[i].da*a;

                    sum+=(team[i].total-a)*team[i].db;

                    b-=(team[i].total-a);

                    a=0;

                }

            }

            else

            {

                if(b>=team[i].total)

                {

                    sum+=team[i].db*team[i].total;

                    b-=team[i].total;

                }

                else

                {

                    sum+=team[i].db*b;

                    sum+=(team[i].total-b)*team[i].da;

                    a-=(team[i].total-b);

                    b=0;

                }

            }

        }

        cout<<sum<<endl;

    }

}

 

你可能感兴趣的:(live)