hdu 1142 A Walk Through the Forest

最短路变形

题意:输入n和m表示图的顶点数和边数然后下面m行给出每条边的信息(无向图)。起点是办公室编号1,终点时家编号2。从1到2,问满足要求的路径条数。要求就是,该条路径经过A点到B点的话,那么经过B点到家的最短路径值要小于A点到家的最短路径值,关于这句话是什么意思,看下面的注释

还好是1A了这题,否则的话感觉要调试很久

//先以家为源点运行一次dij得到家到每个点的最短路(也就是每个点到家的最短路)
//那么从办公室到家的最短路(一条或多条)一定符合题目的要求,因为最短路本身有最优子结构的性质
//还有一些路径,不是办公室到家的最短路,但是它符合题目的要求
//例如办公室为O,家为H,从O到H的最短路中经过C,OC=2,CH=8,即OH=10
//而有另外的一个点B,B到H的最短路BH=5,但OB=6,其实B点并不属于最短路(若0经过B到H长度为11)
//但是BH=5<OH=10,符合题目的意思
//所以我们知道,答案一定大于等于OH最短路的条数
//统计路径的数目用DFS记忆化搜索实现
//c[i]表示i这个点到终点H的路径条数
//c[i]=c[x1]+c[x2]+c[x3]……c[xm],其中x点与i点相连,并且x点最短路值小于i点最短路值

//邻接表建图
//DIJ一遍
//DFS记忆化搜索统计路径数

#include <cstdio>
#include <cstring>
#define N 1050
#define M 2000050
#define INF 0x3f3f3f3f

struct edge
{ int u,v,w,next;}e[M];
int first[N];
int n,en;
int d[N];
bool used[N];
int c[N];

void dfs(int u)
{
    if(c[u]!=-1) return ;

    c[u]=0;
    for(int i=first[u]; i!=-1; i=e[i].next)
    {
        int v=e[i].v;
        if(d[v] < d[u])
        {
            dfs(v);
            c[u]+=c[v];
        }
    }
}

void solve(int s ,int t)
{
    memset(c,-1,sizeof(c));
    c[t]=1;
    dfs(s);
    printf("%d\n",c[s]);
}

void DIJ(int s)
{
    memset(d,0x3f,sizeof(d));
    memset(used,0,sizeof(used));
    d[s]=0;

    for(int nn=1; nn<n-1; nn++)
    {
        int min=INF,k=s;
        for(int i=1; i<=n; i++)
            if(d[i]<min && !used[i])
            { min=d[i]; k=i;}
        used[k]=1;

        for(int i=first[k]; i!=-1; i=e[i].next) //邻接表松弛
        {
            int v=e[i].v , w=e[i].w;
            if(w+d[k] < d[v]) d[v]=d[k]+w;
        }
    }
}

void add(int u ,int v ,int w)
{
    e[en].u=u; e[en].v=v; e[en].w=w;
    e[en].next=first[u]; first[u]=en++;
}

void build()
{
    int m;
    memset(first,-1,sizeof(first));
    en=0;
    scanf("%d",&m);
    for(int i=1; i<=m; i++)
    {
        int u,v,w;
        scanf("%d%d%d",&u,&v,&w);
        add(u,v,w); add(v,u,w);
    }
}

int main()
{
    while(scanf("%d",&n)!=EOF && n)
    {
        build();
        DIJ(2);
        solve(1,2);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/scau20110726/p/2917261.html