POJ3498最大流,枚举终点,企鹅,基础最大流

题意:
      有一n个冰块,每个冰块上都有一些企鹅,所有的企鹅要跳到一个冰块上去,但是由于起跳是的后坐力原因导致每个冰块最多条mi次,最后问你所有的企鹅都跳到一个冰块上去的那块冰块可以是哪一块,输出所有肯能的终点冰块。


思路:
      比较简单,我们可以枚举终点,首先把终点拿出来,剩下的点拆点,拆成两个,限流是最多的跳跃次数,然后起点连接每个拆了的点的左侧的点,终点就是当前枚举的点,然后最大流判断下就行了,提醒下,建图的时候注意,不要多虚拟出来一些没用的点,一开始我的第一感觉就是三重的,后来在敲的时候突然感觉两重就够了,也就是最多200个点就行,还有就是当前枚举的重点的冰块上的企鹅不用动,别的没什么,因为比较简单,我就不解释太多了,不清楚的自己画画建出来的图应该很容易懂。


#include<queue>
#include<stdio.h>
#include<string.h>


#define N_node 200 + 10
#define N_edge 100000
#define INF 1000000000


using namespace std;


typedef struct
{
    int to ,cost ,next;
}STAR;


typedef struct
{
    int x ,t;
}DEP;


typedef struct
{
    double x ,y;
    int p ,c;
}NODE;


NODE node[N_node];
STAR E[N_edge];
DEP xin ,tou;
int list[N_node] ,listt[N_node] ,tot;
int deep[N_node] ,Ans[N_node];
int canlink[110][110];


void add(int a ,int b ,int c)
{
    E[++tot].to = b;
    E[tot].cost = c;
    E[tot].next = list[a];
    list[a] = tot;


    E[++tot].to = a;
    E[tot].cost = 0;
    E[tot].next = list[b];
    list[b] = tot;
}


int minn(int x ,int y)
{
    return x < y ? x : y;
}


bool BFS_DEEP(int s ,int t ,int n)
{
    memset(deep ,255 ,sizeof(deep));
    xin.x = s ,xin.t = 0;
    queue<DEP>q;
    q.push(xin);
    deep[s] = 0;
    while(!q.empty())
    {
        tou = q.front();
        q.pop();
        for(int k = list[tou.x] ;k ;k = E[k].next)
        {
            xin.x = E[k].to;
            xin.t = tou.t + 1;
            if(deep[xin.x] != -1 || !E[k].cost)
            continue;
            deep[xin.x] = xin.t;
            q.push(xin);
        }
    }
    for(int i = 0 ;i <= n ;i ++)
    listt[i] = list[i];
    return deep[t] != -1;
}


int DFS_Flow(int s ,int t ,int flow)
{
    if(s == t) return flow;
    int nowflow = 0;
    for(int k = listt[s] ;k ;k = E[k].next)
    {
        listt[s] = k;
        int c = E[k].cost;
        int to = E[k].to;
        if(!c || deep[to] != deep[s] + 1)
        continue;
        int tmp = DFS_Flow(to ,t ,minn(c ,flow - nowflow));
        nowflow += tmp;
        E[k].cost -= tmp;
        E[k^1].cost += tmp;
        if(nowflow == flow) break;
    }
    if(!nowflow) deep[s] = 0;
    return nowflow;
}


int DINIC(int s ,int t ,int n)
{
    int ans = 0;
    while(BFS_DEEP(s ,t ,n))
    {
        ans += DFS_Flow(s ,t ,INF);
    }
    return ans;
}


double Get_Dis(NODE a ,NODE b)
{
    double x = (a.x - b.x) * (a.x - b.x);
    double y = (a.y - b.y) * (a.y - b.y);
    return x + y;
}


int main ()
{
    int t ,n ,i ,j ,sump;
    double dis;
    scanf("%d" ,&t);
    while(t--)
    {
        scanf("%d %lf" ,&n ,&dis);
        sump = 0;
        for(i = 1 ;i <= n ;i ++)
        {
            scanf("%lf %lf %d %d" ,&node[i].x ,&node[i].y ,&node[i].p ,&node[i].c);
            sump += node[i].p;
        }
        memset(canlink ,0 ,sizeof(canlink));
        for(i = 1 ;i <= n ;i ++)
        for(j = i + 1 ;j <= n ;j ++)
        {
            if(Get_Dis(node[i] ,node[j]) <= dis * dis)
            canlink[i][j] = canlink[j][i] = 1;
        }
        int ansid = 0;
        for(int now = 1 ;now <= n ;now ++)
        {
            memset(list ,0 ,sizeof(list));
            tot = 1;
            for(i = 1 ;i <= n ;i ++)
            {
                if(i == now) continue;
                add(0 ,i ,node[i].p);
                add(i ,i + n ,node[i].c);
            }
            for(i = 1 ;i <= n ;i ++)
            for(j = i + 1 ;j <= n ;j ++)
            {
                if(canlink[i][j])
                {
                    if(i == now) add(j + n ,now ,INF);
                    else if(j == now) add(i + n ,now ,INF);
                    else add(i + n ,j ,INF) ,add(j + n ,i ,INF);
                }
            }
            int flow = DINIC(0 ,now ,n + n);
            if(flow == sump - node[now].p)
            Ans[++ansid] = now;
        }
        if(!ansid) printf("-1 ");
        else
        {
            for(i = 1 ;i <= ansid ;i ++)
            if(i == ansid) printf("%d " ,Ans[i] - 1);
            else printf("%d " ,Ans[i] - 1);
        }
    }
    return 0;
}













原文地址:https://www.cnblogs.com/csnd/p/12062461.html