codeforces 164 C 費用流

來源:互聯網
上載者:User

這是我在codeforces上做的第一個網路流的題目,思維還不錯,講講

題意:給你n個任務,k個機器,n個任務的起始時間,期間,完成任務的獲利

每個機器可以完成任何一項任務,但是同一時刻只能完成一項任務,一旦某台機器在完成某項任務時,直到任務結束,這台機器都不能去做其他任務

最後問你當獲利最大時,應該安排那些機器工作,即輸出方案

 

剛看到題就想到一個貪心的思路,如果一台機器完成了某項工作,它應該繼續去完成接下來最先開始的工作,感覺有點像網路流裡面的建圖啊,於是繼續往這個方向YY,

我擦,結果還真可以網路流來搞。

具體建圖方法:

建立源匯S T‘

對任務按照起始時間s按升序排序

拆點:

u 向 u'連一條邊 容量為 1 費用為 -c,

u' 向 T連一條邊 容量為 inf 費用為 0;

如果任務u完成後接下來最先開始的是任務v

則從u' 向 v連一條邊,容量inf 費用 0.

另外,任務從前往後具有傳遞性,所以必須是第i個任務向第i+1個任務建邊,容量為inf

最後,限制一下起始點向第一個任務的流量即可(即K)

my code

View Code

#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;int Sum_Flow;const int N = 3000;const int M = 100000;const int inf = ~0u>>2;struct Edge{    int u,v,cap,cost;    int next;}edge[M];int E;int head[N],dist[N],pre[N];bool vis[N];void init(){    E=0;    memset(head,-1,sizeof(head));}void add_edge(int u,int v,int cap,int cost){    edge[E].u=u;edge[E].v=v;edge[E].cap=cap;edge[E].cost=cost;    edge[E].next=head[u];head[u]=E++;    edge[E].u=v;edge[E].v=u;edge[E].cap=0;edge[E].cost=-cost;    edge[E].next=head[v];head[v]=E++;}bool spfa(int s,int t,int n){    queue<int> Q;    fill(vis,vis+n+1,false);    fill(pre,pre+n+1,-1);    fill(dist,dist+n+1,inf);    vis[s]=true;dist[s]=0;    Q.push(s);    while(!Q.empty())    {        int u=Q.front();Q.pop();vis[u]=false;        for(int i=head[u];i!=-1;i=edge[i].next)        {            int v=edge[i].v;            if(edge[i].cap && dist[v] > dist[u]+ edge[i].cost)            {                dist[v] = dist[u]+edge[i].cost;                pre[v]=i;                if(!vis[v])                {                    Q.push(v);                    vis[v]=true;                }            }        }    }    if(dist[t] == inf) return false;    return true;}int MCMF(int s,int t,int n){    int flow=0;    int minflow,mincost=0;    while(spfa(s,t,n))    {        minflow=inf+1;        for(int i=pre[t];i!=-1;i=pre[edge[i].u])               if(edge[i].cap < minflow)                   minflow=edge[i].cap;        flow+=minflow;        for(int i=pre[t];i!=-1;i=pre[edge[i].u])        {            edge[i].cap-=minflow;            edge[i^1].cap+=minflow;        }        mincost += dist[t] * minflow;    }    Sum_Flow = flow;    return mincost;}struct node{    int s,t,c;    int id;}in[N];int ans[N];int cmp(node a, node b){    return  a.s<b.s;}int main(){    int n,k;    while(scanf("%d%d",&n,&k)!=EOF)    {        init();        int S = 2*n,T = 2*n+1;        for(int i=0;i<n;i++){            scanf("%d%d%d",&in[i].s,&in[i].t,&in[i].c);            in[i].t=in[i].s+in[i].t-1;            in[i].id=i;        }        sort(in,in+n,cmp);        for(int i=0;i<n;i++)        {            add_edge(i,i+n,1,-in[i].c);            add_edge(i+n,T,inf,0);            if(i<n-1) add_edge(i,i+1,inf,0);            for(int j=i+1;j<n;j++)            {                if(in[i].t<in[j].s)                {                    add_edge(i+n,j,inf,0);                    break;                }            }        }        add_edge(S,0,k,0);        add_edge(n-1,T,k,0);        MCMF(S,T,T+1);        memset(ans,0,sizeof(ans));        for(int i=0;i<E;i+=2)        {            if(!edge[i].cap)            {                int u=edge[i].u,v=edge[i].v;                if(u!=S && u!=T && u<n)                {                    ans[in[u].id]=1;                }            }        }        for(int i=0;i<n;i++) printf("%d ",ans[i]);        puts("");    }    return 0;}

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.