您的位置:首页 > 大数据 > 人工智能

HDU 5294 Tricks Device 2015 Multi-University Training Contest 1 07

2015-07-23 23:00 337 查看
这题是先跑一个最短路,找最短路中最短的边的个数假设为A,那么第二问的答案为M-A,然后根据最短路的建图,求最小割,也就是把最短路的图建权值为1的边,跑一个最大流,注意重边不要删,因为比赛的时候问的,重边不删。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <math.h>
#define maxn 2000
#define maxm 60000
#define qq 200000
#define inf 1000000005
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;

int heads[maxn + 5], heads2[maxn + 5], que[qq + 5], sizes, sizes2, dp[maxn + 5], dis[maxn + 5], p[maxn + 5], f[maxn + 5][maxn + 5], d[maxn + 5], num[maxn + 5], counts, n, m, mi, ans1, ans2, source, sink;
bool vis[maxn + 5];

struct edge
{
    int v, w, next;
}eg[maxm * 2 + 5], eg2[maxm * 2 + 5];

struct node
{
    int v, t, dis;
};

void inits()
{
    mem(vis, 0);
    mem(heads, -1);
    mem(heads2, -1);
    mem(num, 0);
    sizes = 0;
    sizes2 = 0;
    counts = 0;
    return;
}

void add(int u, int v, int w)
{
    eg[sizes].v = v;
    eg[sizes].w = w;
    eg[sizes].next = heads[u];
    heads[u] = sizes++;
    return;
}

void add2(int u, int v)
{
    eg2[sizes2].v = v;
    eg2[sizes2].w = 1;
    eg2[sizes2].next = heads2[u];
    heads2[u] = sizes2++;
    eg2[sizes2].v = u;
    eg2[sizes2].w = 0;
    eg2[sizes2].next = heads2[v];
    heads2[v] = sizes2++;
    return;
}

void spfa()
{
    mem(vis, 0);
    int top = 0, ta = 0;
    for(int i = 2;i <= n;i++)
        dis[i] = dp[i] = inf;
    dis[1] = 0;
    vis[1] = 0;
    dp[1] = 0;
    que[top++] = 1;
    while(ta != top)
    {
        int u = que[ta++];
        ta %= qq;
        for(int i = heads[u];i != -1;i = eg[i].next)
        {
            int v = eg[i].v;
            int w = eg[i].w;
            if(dis[v] > dis[u] + w)
            {
                dis[v] = dis[u] + w;
                dp[v] = dp[u] + 1;
                if(!vis[v])
                {
                    vis[v] = 1;
                    que[top++] = v;
                    top %= qq;
                }
            }
            else if(dis[v] == dis[u] + w)
            {
                dp[v] = min(dp[v], dp[u] + 1);
                if(!vis[v])
                {
                    vis[v] = 1;
                    que[top++] = v;
                    top %= qq;
                }
            }
        }
        vis[u] = 0;
    }
    ans1 = m - dp
;
    return;
}

void build()
{
    for(int i = 1;i <= n;i++)
    {
        for(int j = heads[i];j != -1;j = eg[j].next)
        {
            int v = eg[j].v;
            int w = eg[j].w;
            if(dis[v] - dis[i] == w)
                add2(i, v);
        }
    }
    return;
}

void bfs()
{
    mem(vis, 0);
    d
 = 0;
    num[d
]++;
    int top = 0, ta = 0;
    vis
 = 1;
    que[top++] = n;
    while(top != ta)
    {
        int u = que[ta++];
        ta %= qq;
        for(int i = heads2[u];i != -1;i = eg2[i].next)
        {
            int v = eg2[i].v;
            if(!vis[v])
            {
                vis[v] = 1;
                d[v] = d[u] + 1;
                num[d[v]]++;
                que[top++] = v;
                top %= qq;
            }
        }
    }
    return;
}

int dfs(int a,int cost)
{
    if(a == sink)
        return cost;
    int mins = n - 1, lv = cost, dd;
    for(int i = heads2[a];i != -1;i = eg2[i].next)
    {
        int v = eg2[i].v;
        int w = eg2[i].w;
        if(w)
        {
            if(d[v] + 1 == d[a])
            {
                if(lv < eg2[i].w)
                    dd = lv;
                else
                    dd = eg2[i].w;
                dd = dfs(v, dd);
                eg2[i].w -= dd;
                eg2[i^1].w += dd;
                lv -= dd;
                if(d[source] >= n)
                    return cost - lv;
                if(!lv)
                    break;
            }
            if(d[v] < mins)
                mins = d[v];
        }
    }
    if(lv == cost)
    {
        --num[d[a]];
        if(num[d[a]] == 0)
            d[source] = n;
        d[a] = mins + 1;
        ++num[d[a]];
    }
    return cost - lv;
}

int isap()
{

    source = 1;
    sink = n;
    int ff = 0, st = source;
    while(d[st] < n)
        ff += dfs(st, inf);
    return ff;
}

int main(int argc, char *argv[])
{
    int a, b, c;
	while(~scanf("%d%d", &n, &m))
    {
        inits();
        for(int i = 0;i < m;i++)
        {
            scanf("%d%d%d", &a, &b, &c);
            add(a, b, c);
            add(b, a, c);
        }
        spfa();
        build();
        bfs();
        ans2 = isap();
        printf("%d %d\n", ans2, ans1);
    }
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: