网络流24题13

https://loj.ac/problem/6015

着重理解这题的建图是按照时间的分层图,对于时刻t的n个站点,他们的人员有2种来源 ,一是上一个时刻停留在该点的人员,另一种就是t-1通过飞船过来的人,对于每个新时刻维护好这几个边就行了

然后并查集判断有无解

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
using namespace std;
const int maxn = 50;
const int inf = 0x3f3f3f3f;
int fa[maxn];
int cap[maxn];
int head[maxn*1000];
int all[maxn];
struct edge{
    int v,nex,w;
}e[maxn*1000];
int tot  = 0;
void addedge(int u,int v,int w){
    e[tot] = (edge){v,head[u],w};
    head[u] = tot++;
    e[tot] = (edge){u,head[v],0};
    head[v] = tot++;
}
vector<int> v[maxn];
int find(int now){
    if(fa[now]== now) return now;
    return find(fa[now]);
}
void un(int u,int v){
    int fau = find(u);
    int fav = find(v);
    if(fau!=fav){
        fa[fau] = fa[fav];
    }
}
int deep[maxn*100];
bool bfs(int S,int T){
    memset(deep, 0, sizeof(deep));
    deep[S] = 1;
    queue<int> q;
    q.push(S);
    while (!q.empty()) {
        int now = q.front();
        q.pop();
        for(int i=head[now];i!=-1;i=e[i].nex){
            int w = e[i].w;
            int v = e[i].v;
            if(deep[v]!=0 || w<=0) continue;
            deep[v] = deep[now]+1;
            q.push(v);
        }
    }
    return deep[T];
}
int dfs(int now,int T,int maxflow){
    if(now==T) return maxflow;
    int all = 0;
    for(int i=head[now];i!=-1 && all<maxflow;i=e[i].nex){
        int v = e[i].v;
        int w = e[i].w;
        if(deep[v]!=deep[now]+1 || w<=0) continue;
        int tt = dfs(v,T,min(maxflow-all,w));
        e[i].w-=tt;
        e[i^1].w+=tt;
        all+=tt;
    }
    return all;
}
int main(int argc, const char * argv[]) {
    memset(head, -1, sizeof(head));
    int n,m,k;
    scanf("%d%d%d",&n,&m,&k);
    for(int i=0;i<=n+1;i++){
        fa[i] = i;
    }
    int S = 0;
    int T = 1;
    for(int i=0;i<m;i++){
        scanf("%d",&cap[i]);
        scanf("%d",&all[i]);
        for(int j=0;j<all[i];j++){
            int tmp ;
            scanf("%d",&tmp);
            tmp++;
            v[i].push_back(tmp);
            if(j!=0){
                un(v[i][0],tmp);
            }
        }
    }
    if(find(0)!=find(1)){
        puts("0");
        return 0;
    }
    int ans;
    int maxflow = 0;
    addedge(S, 1+1*(n+2), inf);
    addedge(1*(n+2), T, inf);
    for(int i=0;i<n+2;i++){
        addedge(i+1*(n+2), i+(1+1)*(n+2), inf);
    }
    for(ans=2;;ans++){
        addedge(S, 1+ans*(n+2), inf);
        addedge(ans*(n+2), T, inf);
        for(int i=0;i<m;i++){
            int from = v[i][(ans-2+all[i])%all[i]];
            int to = v[i][(ans-1+all[i])%all[i]];
            addedge(from+(ans-1)*(n+2), to+ans*(n+2), cap[i]);
        }
        while (bfs(S,T)) {
            maxflow+=dfs(S,T,inf);
        }
        if(maxflow>=k) break;
        for(int i=0;i<n+2;i++){
            addedge(i+ans*(n+2), i+(ans+1)*(n+2), inf);
        }
    }
    printf("%d\n",ans-1);
    return 0;
}

  

posted @ 2018-03-28 02:07  tjucxz  阅读(93)  评论(0编辑  收藏  举报