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;

}

 

你可能感兴趣的:(REST)