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

来源:互联网 发布:学校宿舍网络设计 编辑:程序博客网 时间:2024/05/01 22:05
  这题是先跑一个最短路,找最短路中最短的边的个数假设为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[n];    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[n] = 0;    num[d[n]]++;    int top = 0, ta = 0;    vis[n] = 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;}

0 0
原创粉丝点击