【最小割】ustc 1280

來源:互聯網
上載者:User

http://acm.ustc.edu.cn/ustcoj/problem.php?id=1280

這題是中國科大“百分點科技杯"ACM除夕挑戰賽 的題目,當時做不出,後來想了一下,TLE1次,wa一次就過了

這題去掉最小費用和的邊使得最短路變長,方法是先求一次最短路,然後建新圖,圖中存在的邊若且唯若(u,v) dis[u]+w(u,v)=dis[v],題目就變成求切掉最小的邊,切完後最短路必然變大,然後最小割=最大流就可做了,具體實現上就要使得if(dis[u] + e[i].w != dis[v]) e[i].c
= 0;把容量變為0就等於切斷了邊,最短路套spfa模板,網路流套sap模板

Code:

#define inf 1<<30#define N 1004#define sta queconst int INF = (1<<30);struct edge{    int u,v,w,c;    int next;//同一起點的下一條邊儲存在edge數組中的位置(理解了這個靜態鄰接表就可以了)}e[N*25];int head[N];//以該點為起點的第一條邊儲存在e數組中的位置int dis[N];//記錄與源點距離bool vis[N];//記錄頂點是否在隊列中,SPFA演算法可以入隊列多次int cnt[N];//記錄頂點入隊列次數int ecnt;int n,m;void init(){    ecnt = 0;    memset(head,-1,sizeof(head));}void add(int u,int v,int w,int cost){    e[ecnt].u = u;    e[ecnt].v = v;    e[ecnt].w = w;    e[ecnt].c = cost;    e[ecnt].next = head[u];    head[u] = ecnt++;//位置更新    /////////////////////////////    e[ecnt].u = v;    e[ecnt].v = u;    e[ecnt].w = w;    e[ecnt].c = cost;    e[ecnt].next = head[v];    head[v] = ecnt++;}bool SPFA(int s){//s是源點編號    queue<int>  qq;    int i;    for(i=1;i<=n;++i){        dis[i] = INF;        //將除源點以外的其餘點的距離設定為無窮大        vis[i] = 0;        cnt[i] = 0;    }    dis[s]=0;              //源點的距離為0    vis[s] = 1;    cnt[s]++;            //源點的入隊列次數增加    qq.push(s);    int u,v;    while(!qq.empty()){        u = qq.front();        qq.pop();        vis[u] = 0;        for(i=head[u];i!=-1;i = e[i].next){            v = e[i].v;            int cost = e[i].w;            if(dis[v] > cost+dis[u]){                dis[v] = cost+dis[u];                if(!vis[v]){                    vis[v] = 1;                    qq.push(v);                    cnt[v]++;                    if(cnt[v] >= n)return false;                }            }        }    }    return true;}int h[N];int gap[N];int source,sink;inline int dfs(int pos,int cost){    if (pos==sink){        return cost;    }    int j,minh=n-1,lv=cost,d;    for (j=head[pos];j!=-1;j=e[j].next){        int v=e[j].v,val=e[j].c;        if(val>0){            if (h[v]+1==h[pos]){                if (lv<e[j].c) d=lv;                else d=e[j].c;                d=dfs(v,d);                e[j].c-=d;                e[j^1].c+=d;                lv-=d;                if (h[source]>=n) return cost-lv;                if (lv==0) break;            }            if (h[v]<minh)   minh=h[v];        }    }    if (lv==cost){        --gap[h[pos]];        if (gap[h[pos]]==0) h[source]=n;        h[pos]=minh+1;        ++gap[h[pos]];    }    return cost-lv;}int sap(int st,int ed){    source=st;    sink=ed;    int ans=0;    memset(gap,0,sizeof(gap));    memset(h,0,sizeof(h));    gap[st]=n;    while (h[st]<n){        ans+=dfs(st,INT_MAX);    }    return ans;}int main(){    int s,t;    int ca=1;    while(scanf("%d%d",&n,&m) && (n+m)){        int i,j;        scanf("%d%d",&s,&t);        init();        for(i=0;i<m;i++){            int u,v,w,c;            scanf("%d%d%d%d",&u,&v,&w,&c);            add(u,v,w,c);        }        SPFA(s);//cout<<ecnt<<endl;        for(i=0;i<ecnt;i+=2){            int u = e[i].u;            int v = e[i].v;            //if(u==1 && v==4){e[i].c=0;e[i+1].c=1;continue;}            if(dis[u] + e[i].w != dis[v]){                e[i].c = 0;            }            if(dis[v] + e[i].w != dis[u]){                e[i+1].c=0;            }        }        //for(i=0;i<ecnt;i++)cout<<e[i].u<<" "<<e[i].v<<" "<<e[i].c<<endl;        printf("Case %d: %d\n",ca++,sap(s,t));    }    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.