poj 1087.A Plug for UNIX 解題報告

來源:互聯網
上載者:User

標籤:style   blog   http   color   io   os   ar   for   div   

網路流,關鍵在建圖

建圖思路在代碼裡

/*      最大流SAP      鄰接表      思路:基本源於FF方法,給每個頂點設定層次標號,和允許弧。      最佳化:      1、當前弧最佳化(重要)。      1、每找到以條增廣路回退到斷點(常數最佳化)。      2、層次出現斷層,無法得到新流(重要)。      時間複雜度(m*n^2)*/#include <iostream>#include <cstdio>#include <cstring>#include <map>#define ms(a,b) memset(a,b,sizeof a)using namespace std;const int INF = 500;struct node {    int v, c, next;} edge[INF*INF * 4];int  pHead[INF*INF], SS, ST, nCnt;void addEdge (int u, int v, int c) {    edge[++nCnt].v = v; edge[nCnt].c = c, edge[nCnt].next = pHead[u]; pHead[u] = nCnt;    edge[++nCnt].v = u; edge[nCnt].c = 0, edge[nCnt].next = pHead[v]; pHead[v] = nCnt;}int SAP (int pStart, int pEnd, int N) {    int numh[INF], h[INF], curEdge[INF], pre[INF];    int cur_flow, flow_ans = 0, u, neck, i, tmp;    ms (h, 0); ms (numh, 0); ms (pre, -1);    for (i = 0; i <= N; i++) curEdge[i] = pHead[i];    numh[0] = N;    u = pStart;    while (h[pStart] <= N) {        if (u == pEnd) {            cur_flow = 1e9;            for (i = pStart; i != pEnd; i = edge[curEdge[i]].v)                if (cur_flow > edge[curEdge[i]].c) neck = i, cur_flow = edge[curEdge[i]].c;            for (i = pStart; i != pEnd; i = edge[curEdge[i]].v) {                tmp = curEdge[i];                edge[tmp].c -= cur_flow, edge[tmp ^ 1].c += cur_flow;            }            flow_ans += cur_flow;            u = neck;        }        for ( i = curEdge[u]; i != 0; i = edge[i].next)            if (edge[i].c && h[u] == h[edge[i].v] + 1)     break;        if (i != 0) {            curEdge[u] = i, pre[edge[i].v] = u;            u = edge[i].v;        }        else {            if (0 == --numh[h[u]]) continue;            curEdge[u] = pHead[u];            for (tmp = N, i = pHead[u]; i != 0; i = edge[i].next)                if (edge[i].c)  tmp = min (tmp, h[edge[i].v]);            h[u] = tmp + 1;            ++numh[h[u]];            if (u != pStart) u = pre[u];        }    }    return flow_ans;}/*       poj1087 最大流       建圖:       每個種插座和為一個節點,添加源點和匯點       源點到每個存在的插座連一條容量為插座數量的邊       統計需要每種插座的數量,作為插座到匯點邊的容量       如果有轉換器A->B,AB串連一條容量無限的邊*/int k, m, n, tol;int sum[INF], need[INF];map<string, int> mat;string s,ss;int main() {    /*           前向星存邊,表頭在pHead[],初始化nCnt=1           SS,ST分別為源點和匯點    */    nCnt = 1;    cin >> n;    for (int i = 1; i <= n; i++) {        cin >> s;        if (mat.find (s) == mat.end() ) mat[s] = ++tol;        sum[tol]++;    }    cin >> m;    for (int i = 1; i <= m; i++) {        cin >> ss >> s;        if (mat.find (s) == mat.end() ) mat[s] = ++tol;        need[mat[s]]++;    }    cin>>k;    for (int i=1;i<=k;i++){           cin>>ss>>s;           if (mat.find (s) == mat.end() ) mat[s] = ++tol;           if (mat.find (ss) == mat.end() ) mat[ss] = ++tol;              int u=mat[s],v=mat[ss];              addEdge(u,v,100);    }    SS=tol+1,ST=tol+2;    for(int i=1;i<=tol;i++){              addEdge(SS,i,sum[i]);              addEdge(i,ST,need[i]);    }    int ans=SAP(SS,ST,ST);    cout<<m-ans<<endl;       return 0;}
View Code

 

poj 1087.A Plug for UNIX 解題報告

聯繫我們

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