(最小費用最大流模板)HDU 3488

/*
    Created by mowenwen
     ~~~~   2015.10.01
*/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
#define maxn 10000+10
#define inf 0x7fffffff
int k, p;
int tot;
int head[maxn],flag[maxn],p1[maxn],p2[maxn],dis[maxn];
struct Edge
{
    int to,next,c,f;
}edge[80010];
void addedge(int u,int v,int c,int f)

    int i;                         //去重邊
    for(i = head[u];i != -1;i = edge[i].next)
    {
        if(edge[i].to == v)
            break;
    }
    if(i != -1)
    {
        if(f < edge[i].f)
        {
            edge[i].f = f;
            edge[i^1].f = -f;
        }
        return;
    }
    edge[tot].next = head[u];
    edge[tot].to = v;
    edge[tot].c = c;
    edge[tot].f = f;
    head[u] = tot ++;
    edge[tot].next = head[v];
    edge[tot].to = u;
    edge[tot].c = 0;
    edge[tot].f = -f;
    head[v] = tot ++;
    return;
}
bool spfa(int s, int t)
{
    queue<int> q;
    memset(flag, 0, sizeof(flag));
    memset(p1, -1, sizeof(p1));
    memset(p2, -1, sizeof(p2));
    for(int i = 0;i <= t;i ++)
    dis[i] = inf;
    q.push(s);
    dis[s] = 0;
    flag[s] = 1;
    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        flag[u] = 0;
        for(int i = head[u]; i != -1; i = edge[i].next)
        {
           if(edge[i].c)
           {
               int v = edge[i].to;
               if(dis[v] > dis[u] + edge[i].f)
               {
                   dis[v] = dis[u] + edge[i].f;
                   p1[v] = u;      //當前點的前驅
                   p2[v] = i;      //當前點所連的邊
                   if(!flag[v])
                   {
                       q.push(v);
                       flag[v] = 1;
                   }

               }
           }

        }
    }
    if(dis[t] == inf) return false;
    else return true;
}
int min_cost_flow(int s,int t)
{
   int ans_cost = 0;
   int u, minn;
   while(spfa(s, t))
   {
       u = t;
       minn = inf;
       while(p1[u] != -1)
       {
           minn = min(minn, edge[p2[u]].c);
           u = p1[u];
       }
       //cout << minn <<endl;
       u = t;
       while(p1[u] != -1)
       {
           edge[p2[u]].c -= minn;
           edge[p2[u] ^ 1].c += minn;
           u = p1[u];
       }
       ans_cost += dis[t] * minn;
       //cout << ans_cost<<endl;
   }
   return ans_cost;
}
void init()
{
     memset(head, -1, sizeof(head));
     tot = 0;
}
int main()
{
    int t, n, m, u, v, w;
    scanf("%d", &t);
    while(t --)
    {
        scanf("%d%d", &n, &m);
        for(int i = 0;i < m;i ++)
        {
            scanf("%d%d%d",&u, &v, &w);
            addedge(u, v+n, 1, w);
        }
        for(int i = 1;i <= n;i ++)
        {
            addedge(0, i, 1, 0);
        }
        for(int i = n+1;i <= 2*n;i ++)
        {
            addedge(i, 2*n+1, 1, 0);
        }
        int ans = min_cost_flow(0, 2*n+1);
        printf("%d\n", ans);
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章