zoukankan      html  css  js  c++  java
  • uva10917

    题意实际上是在原图中对于一条边(a,b)如果d[a] > d[b]则在新图中连b->a的一条边。

    最后求有向图的路径总数。

    用dp实现。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    
    using namespace std;
    
    const int maxn = 1005, maxm = maxn * maxn, inf = 1e9;
    
    struct node
    {
        int u, d;
        bool operator < (const node& rhs) const
        {
            return d > rhs.d;
        }
    };
    
    priority_queue<node> q;
    
    int n, m, tot;
    
    int h[maxn], done[maxn], dis[maxn], vis[maxn], d[maxn];
    
    struct edge
    {
        int v, next, w;
    }a[maxm], a2[maxm];
    
    int h2[maxn];
    
    int tot2;
    
    void add(int x, int y, int z)
    {
        a[tot].v = y;
        a[tot].w = z;
        a[tot].next = h[x];
        h[x] = tot++;
    }
    
    void add2(int x, int y, int z)
    {
        a2[tot2].v = y;
        a2[tot2].w = z;
        a2[tot2].next = h2[x];
        h2[x] = tot2++;
    }
    
    int dp(int u)
    {
        if (vis[u]) return d[u];
        vis[u] = 1;
        if (u == 2) return d[2] = 1;
        d[u] = 0;
        for (int i = h2[u]; ~i; i = a2[i].next)
        {
            int v = a2[i].v;
            d[u] += dp(v);
        }
        return d[u];
    }
    
    int main()
    {
    //    freopen("uva10917.in","r",stdin);
        while (scanf("%d%d", &n, &m) && n && m)
        {
            memset(h, -1, sizeof h); tot = 0;
            for (int i = 1; i <= m; i++)
            {
                int x, y, z;
                scanf("%d%d%d", &x, &y, &z);
                add(x, y, z); add(y, x, z);
            }
            for (int i = 1; i <= n; i++)
                dis[i] = inf;
            dis[2] = 0;
            q.push((node){2, 0});//题目中说2是这个人的家,也就是终点 
            memset(done, 0 ,sizeof done);
            while (!q.empty())
            {
                node x = q.top(); q.pop();
                int u = x.u;
                if (done[u]) continue;
                done[u] = 1;
                for (int i = h[u]; ~i; i = a[i].next)
                {
                    int v = a[i].v;
                    if (dis[u] + a[i].w < dis[v])
                    {
                        dis[v] = dis[u] + a[i].w;
                        q.push((node){v,dis[v]});
                    }
                }
            }
            memset(h2, -1, sizeof h2); tot2 = 0;
            memset(vis, 0, sizeof vis);
            memset(d, 0, sizeof d);
            for (int i = 1; i <= n; i++)
                for (int j = h[i]; ~j; j = a[j].next) 
                {
                    int v = a[j].v;
                    if (dis[i] < dis[v]) add2(v, i, a[j].w);//把新图搞出来 
                }
            printf("%d
    ", dp(1));
        }
        return 0;
    }
  • 相关阅读:
    《设计模式》(精华集)
    TClientDataSet使用(二)
    害我查了半天的错误!av错误,小心Component对象使用Application当Owner
    释放自己
    最近在转C#
    TClientDataSet的使用技巧
    小心使用可修改的常量。
    指数函数和正弦函数相乘
    adb 常用命令
    win7下ie9设置无法保存的问题
  • 原文地址:https://www.cnblogs.com/yohanlong/p/7772656.html
Copyright © 2011-2022 走看看