1142 hdu (最短路 + DFS)

来源:互联网 发布:网络的坏处例子 编辑:程序博客网 时间:2024/05/17 07:51

#include <iostream>//2564308 2010-07-01 11:08:17 Accepted 1142 109MS 4192K 1557 B C++ 悔惜晟
#include <cstdio>
#include <cstring>
using namespace std;

const int N = 1005;
int cost[N][N];
int dis[N];
int count[N];
bool hash[N];
int n;
const int MAX = 0x7fffffff;

void Dijsktra()
{
 int i, j, k;
 memset(hash,false, sizeof(hash));
 for(i = 1; i <= n; i++)
  dis[i] = cost[2][i];
 hash[2] = true;
 dis[2] = 0;
 for(i = 1; i < n ; i++)
 {
  int d = MAX;
  k = 1;
  for(j = 1; j <= n; j++)
  {
   if(dis[j] < d && !hash[j])
   {
    d = dis[j];
    k = j;

   }
  }
  hash[k] = true;
  for(j = 1; j <= n; j++)
  {
   if(!hash[j] && cost[k][j] != MAX && dis[j] > dis[k] + cost[k][j])
    dis[j] = dis[k] + cost[k][j];
  }
 }
}

int DFS(int k)
{
 if(count[k] != -1)
  return count[k];
 if(k == 2)
  return 1;
 int temp , sum = 0;
 for(int i = 1; i <= n; i++)
 {
  if(cost[i][k] != MAX && dis[k] > dis[i])
  {
   temp = DFS(i);
   sum += temp;
  }
 }
 count[k] = sum;
 return sum;
}

int main()
{
 int m, i, j, a, b, t;
 while(scanf("%d", &n) != EOF && n)
 {
  scanf("%d", &m);
  for(i = 1; i <= n; i++)
  for(j = 1; j <= n; j++)
  {
   if(i == j)
    cost[i][j] = 0;
   else
    cost[i][j] = MAX;
   count[i] = -1;
  }
  for(i = 0; i < m; i++)
  {
   scanf("%d %d %d", &a, &b, &t);
   cost[a][b] = t;
   cost[b][a] = t;            
  }
  Dijsktra();
  /*
  int count = 0;
  for(i = 1; i <= n; i++)
  for(j = i + 1; j <= n; j++)
  {
   if(cost[i][j] != MAX && dis[i] < dis[j])
    count++;
  }
  */
  DFS(1);
  printf("%d/n",count[1]);
 }
}

//参考如下代码才有点弄懂的,DFS还是不会啊。。
// 这个不错,只是邻接表不会,要快点学啊。http://zc634579757.blog.163.com/blog/static/124497462200992602033748/
#include<iostream>
using namespace std;
int n;//十字路口数
int map[1001][1001];
int dist[1001],dp[1001];
void dijkstra(int v)//迪杰斯特拉算法
{
    int i,j,mins,index;
    int *s = new int[n+1];
    for(i=1;i<=n;i++)
    {
        dist[i] = map[i][v];
        s[i] = 0;
    }
    dist[v] = 0;
    s[v] = 1;
    for(i=1;i<n;i++)
    {
        mins = 2000000;
        for(j=1;j<=n;j++)
        {
            if(s[j]==0 && dist[j]<mins)
            {
                mins = dist[j];
                index = j;
            }
        }
        if(mins == 2000000)
            break;
        s[index] = 1;
        for(j=1;j<=n;j++)
        {
            if(s[j]==0 && dist[j]>dist[index]+map[j][index])
                dist[j] = dist[index]+map[j][index];
        }
    }
}

int dfs(int v)//记忆法深搜
{
    if(dp[v] != -1)
        return dp[v];
    if(v == 2)
        return 1;
    int i,temp,sum=0;   
    for(i=1;i<=n;i++)
    {
        if(map[v][i]!=2000000 && dist[v] > dist[i])//有路相通而且要去的i点到终点站的距离要比v到终点站的距离小
        {
            temp = dfs(i);
            sum += temp;
        }
    }
    dp[v] = sum;
    return sum;
}

int main()
{
    while(cin>>n && n)
    {
        int i,j,d,m;
        cin>>m;
        for(i=1;i<=n;i++)
        {
            dp[i] = -1;
            for(j=1;j<=n;j++)
                map[i][j] = 2000000;
        }
        while(m--)
        {
            scanf("%d%d%d",&i,&j,&d);
            map[i][j] = map[j][i] = d;//无向图
        }
        //求出各点到终点站的最短距离
        dijkstra(2);//2为终点站
        dfs(1);//从1出发
        cout<<dp[1]<<endl;
    }
    return 0;
}

原创粉丝点击