hdoj 2883 kebab 【經典最大流】

來源:互聯網
上載者:User

標籤:資料   網路流最大流   dfs   bfs   

題目:hdoj 2883 kebab 


題意:現在有n個人要烤肉,有m個烤肉架,然後給出每個人的烤肉開始時間si,結束時間ei,以及要烤肉的串數num,還有拷一串的時間ti,然後問你能不能滿足所有人的要求。


分析:這是一個比較經典的最大流,經典在於建圖方法,這個題目痛點在於時間跨度在0---100 0000,如果時間短的話就可以用題目3572的做法了。點擊開啟連結

後面看了別人的建圖方法,確實比較經典,經典在於把區間縮點了,這個題目的痛點在於時間跨度大,那麼我們可以把所有的時間點記錄下來,然後排序,然後以這些時間點建圖。

建圖方案:

首先超級源點s到每個人 i 建容量為 num * ti 邊,

然後對於每個人的烤肉時間區間,枚舉排序之後的所有的相鄰時間點,相鄰兩點也組成一個區間,那麼假如枚舉的區間包含在這個人的時間區間內,從人 i 建邊 區間 j,容量inf

然後每個區間開始點 j 建邊到超級匯點建邊容量為(time【j+1】-time【j】)*m。

這樣,如果最大流為所有的count(num * ti),則滿足要求。

範例1建圖之後得到這樣的圖:



這個題目也是用c++提交的,G++編譯錯誤,不解。

AC代碼:

#include <cstdio>#include <cstring>#include <iostream>#include <string>#include <algorithm>#include <vector>#include <queue>using namespace std;#define Del(a,b) memset(a,b,sizeof(a))const int N = 1020;const int inf = 0x3f3f3f3f;int n,m;int Min(int a,int b){return a>b?b:a;}struct Node{    int from,to,cap,flow;};vector<int> v[N];vector<Node> e;int vis[N];  //構建層次圖int cur[N];void add_Node(int from,int to,int cap){Node tmp1,tmp2;tmp1.cap=from=from,tmp1.to=to,tmp1.cap=cap,tmp1.flow=0;    e.push_back(tmp1);tmp2.from=to,tmp2.to=from,tmp2.cap=0,tmp2.flow=0;    e.push_back(tmp2);    int tmp=e.size();    v[from].push_back(tmp-2);    v[to].push_back(tmp-1);}bool bfs(int s,int t){    Del(vis,-1);    queue<int> q;    q.push(s);    vis[s] = 0;    while(!q.empty())    {        int x=q.front();        q.pop();        for(int i=0;i<v[x].size();i++)        {            Node tmp = e[v[x][i]];            if(vis[tmp.to]<0 && tmp.cap>tmp.flow)  //第二個條件保證            {                vis[tmp.to]=vis[x]+1;                q.push(tmp.to);            }        }    }    if(vis[t]>0)        return true;    return false;}int dfs(int o,int f,int t){    if(o==t || f==0)  //最佳化        return f;    int a = 0,ans=0;    for(int &i=cur[o];i<v[o].size();i++) //注意前面 ’&‘,很重要的最佳化    {        Node &tmp = e[v[o][i]];        if(vis[tmp.to]==(vis[o]+1) && (a = dfs(tmp.to,Min(f,tmp.cap-tmp.flow),t))>0)        {            tmp.flow+=a;            e[v[o][i]^1].flow-=a; //存圖方式            ans+=a;            f-=a;            if(f==0)  //注意最佳化                break;        }    }    return ans;  //最佳化}int dinci(int s,int t){    int ans=0;    while(bfs(s,t))    {        Del(cur,0);        int tm=dfs(s,inf,t);        ans+=tm;    }    return ans;}struct Node1{    int si,num,ei,ti;};Node1 a[250];vector<int> time;int main(){    //freopen("Input.txt","r",stdin);    int n,m;    while(~scanf("%d%d",&n,&m))    {        int s=0,t=3*n+2,count=0,i,j;        for(i=1;i<=n;i++)        {            scanf("%d%d%d%d",&a[i].si,&a[i].num,&a[i].ei,&a[i].ti);            time.push_back(a[i].si);            time.push_back(a[i].ei);            int tmp = a[i].num*a[i].ti;            count+=tmp;            add_Node(s,i,tmp);        }        sort(time.begin(),time.end());        for(i=1;i<=n;i++)        {            for(j=0;j<(time.size()-1);j++)            {                if(a[i].si<=time[j] && a[i].ei>=time[j+1]){                    add_Node(i,n+j+1,inf);                    //printf("-%d ",time[j]);                }            }        }        for(i=0;i<(time.size()-1);i++)            add_Node(n+i+1,t,(time[i+1]-time[i])*m);        int ans=dinci(s,t);        //printf("%d\n",ans);        if(ans==count)            printf("Yes\n");        else            printf("No\n");        for(i=0;i<=t;i++)            v[i].clear();        e.clear();time.clear();    }    return 0;}


hdoj 2883 kebab 【經典最大流】

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.