HDU 3435

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
#define maxn 3000
#define inf 0x7ffffff
int t, n, m, tot;
int ans_flow;
int head[maxn], p1[maxn], p2[maxn], flag[maxn], dis[maxn];
struct Edge
{
    int to, next, c, f;
}edge[60500];
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(edge[i].f > f)
        {
            edge[i].f = f;
            edge[i^1].f = -f;
        }
        return;
    }
    edge[tot].to = v;
    edge[tot].c = c;
    edge[tot].f = f;
    edge[tot].next = head[u];
    head[u] = tot ++;

    edge[tot].to = u;
    edge[tot].c = 0;
    edge[tot].f = -f;
    edge[tot].next = head[v];
    head[v] = tot ++;
}
void init()
{
    tot = 0;
    memset(head, -1, sizeof(head));
}
bool spfa(int s, int t)
{
    int u;
    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;
    dis[s] = 0;
    q.push(s);
    flag[s] = 1;
    while(!q.empty())
    {
        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;
    return true;
}
int min_cost_max_flow(int s, int t)
{
    int ans_min = 0, u, minn;
    ans_flow = 0;
    while(spfa(s, t))
    {
        u = t;
        minn = inf;
        while(p1[u] != -1)
        {
            minn = min(minn, edge[p2[u]].c);
            u = p1[u];
        }
        u = t;
        while(p1[u] != -1)
        {
            edge[p2[u]].c -= minn;
            edge[p2[u]^1].c += minn;
            u = p1[u];
        }
        ans_min += dis[t]*minn;
        ans_flow += minn;
    }
    return ans_min;
}
int main()
{
    int u, v, w;
    scanf("%d", &t);
    int cas = 1;
    while(t --)
    {
        init();
        scanf("%d %d", &n, &m);
        for(int i = 1;i <= m;i ++)
        {
            scanf("%d %d %d",&u, &v, &w);
            addedge(u, n+v, 1, w);
            addedge(v, n+u, 1, w);
        }
        for(int i = 1;i <= n;i ++)
        {
            addedge(0, i, 1, 0);
            addedge(i+n, 2*n+1, 1, 0);
        }
        int ans = min_cost_max_flow(0, 2*n+1);

        if(ans_flow == n)
        printf("Case %d: %d\n", cas++, ans);
        else
        printf("Case %d: NO\n", cas++);
    }
    return 0;
}

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