UVA1324 拆点 小心坑!

来源:互联网 发布:免费网络教育平台 编辑:程序博客网 时间:2024/04/29 13:20

题目描述不多说 思路把一个点拆成T个 不断枚举T并往图上连边加点 知道最大流等于k 最后打印方案 因为原弧和其反向弧总是在一起 所以可以直接枚举检验时候有流量 

处理 a->b b->a的方法 显然这两条边是续加入的 可快速找到对应的边 统计流量 如果同时有流量则不移动

特别注意!!! s进行最大流算法是要在刚好满足的时刻退出 不然会导致不存在的流量出现


#include<cstdio>#include<algorithm>#include<cstring>#include<queue>#define MAXN 6000#define MAXM 3000000#define MAXK 500const int INF = 0x3f3f3f3f;using namespace std;typedef pair<int, int> pii;pii A[200+10];int Move[MAXK+10], pos[MAXK+10];int n, m, S, T, k;template <int maxn, int maxm>struct Isap{    int ecnt;    int d[maxn+10], pre[maxn+10], cur[maxn+10], gap[maxn+10];    int adj[maxn+10];    struct node {        int v, next, c, f;    }Edge[maxm*2+10];    void init() { memset(adj, -1, sizeof(adj)); ecnt = 0; }    void addedge(int u, int v, int c)    {        Edge[ecnt].v = v;        Edge[ecnt].c = c;        Edge[ecnt].f = 0;        Edge[ecnt].next = adj[u];        adj[u] = ecnt++;    }    void add(int u, int v, int c)    {        addedge(u, v, c);        addedge(v, u, 0);    }    void init_dis(int t) // 据说单次意义不大的优化 多次小规模才会出现差距 仅仅是据说    {        queue <int> q;        memset(d, -1, sizeof(d));        memset(gap, 0, sizeof(gap));        d[t] = 0;        q.push(t);        while(!q.empty())        {            int u = q.front(); q.pop();            gap[d[u]]++;            for(int i = adj[u]; ~i; i = Edge[i].next)             {                int v = Edge[i].v;                if(d[v] == -1) { d[v] = d[u] + 1; q.push(v); }            }        }    }    int ISAP(int s, int t, int num, int limit)    {        init_dis(t);        int ans = 0, u = s;        int Flow = INF;        memcpy(cur, adj, sizeof(adj));        while(d[s] < num)        {            int &i = cur[u];            for(; ~i; i = Edge[i].next)            {                int v = Edge[i].v;                if(Edge[i].c > Edge[i].f && d[u] == d[v] + 1)                {                    u = v;                    pre[v] = i;                    Flow = min(Flow, Edge[i].c - Edge[i].f);                    if(u == t)                    {                         while(u != s) {                            int j = pre[u];                            Edge[j].f += Flow;                            Edge[j^1].f -= Flow;                            u = Edge[j^1].v;                        }                        ans += Flow;                        Flow = INF;                    }if(ans == limit) return ans;                    break;                }            }            if(i == -1)            {                if(--gap[d[u]] == 0) break;                int dmin = num - 1;                cur[u] = adj[u];                for(int j = adj[u]; ~j; j = Edge[j].next) if(Edge[j].c > Edge[j].f) dmin = min(dmin, d[Edge[j].v]);                d[u] = dmin+1;                gap[d[u]]++;                if(u != s) u = Edge[pre[u]^1].v;            }        }        return ans;    }};  Isap <MAXN+10, MAXM+10> sap;vector <pii> step;void print_ans(int Day){int id = 0;for(int i = 0; i < k; i++) pos[i] = S;for(int i = 1; i <= Day; i++){id += 2 * n;int j = 1;step.clear();for(int j = 0; j < m; j++){int f1 = sap.Edge[id].f; id += 2;int f2 = sap.Edge[id].f; id += 2;if(f1 && !f2) step.push_back(make_pair(A[j].first % n, A[j].second % n));else if(!f1 && f2) step.push_back(make_pair(A[j].second % n, A[j].first % n));}printf("%d", step.size());memset(Move, 0, sizeof(Move));for(int j = 0; j < step.size(); j++){int u = step[j].first, v = step[j].second;for(int p = 0; p < k; p++)if(!Move[p] && pos[p] == u){Move[p] = 1;printf(" %d %d", p+1, v+1);pos[p] = v;break;}}printf("\n");}  }int main(){while(scanf("%d%d%d%d%d", &n, &m, &k, &S, &T) == 5){S--; T--;sap.init();int Day = 1, Flow = 0;for(int i = 0; i < m; i++) {int u, v;scanf("%d%d", &u, &v);u--; v--;A[i] = make_pair(u, v);}for(;;){int Last = (Day-1) * n, Now = Day * n;for(int i = 0; i < n; i++)sap.add(Last+i, Now+i, INF);for(int i = 0; i < m; i++){int u = A[i].first, v = A[i].second;sap.add(Last+u, Now+v, 1);sap.add(Last+v, Now+u, 1);}Flow += sap.ISAP(S, T + Now, (Day + 1) * n, k - Flow);if(Flow >= k) break;Day++;}printf("%d\n", Day);print_ans(Day);}}


0 0
原创粉丝点击