Dijkstra解决POJ 2263

◇◆丶佛笑我妖孽 提交于 2020-01-25 18:03:21

 

题目:http://poj.org/problem?id=2263

题目大意:有n个城市,r条连接两个城市的道路,每条道路有自己的最大复载量。现在问从城市cst到城市cen,车上的最大载重能为多少。

 
虽然是提交了,也搞懂了,但是还没有彻底的明白。
因此,也不便多说什么,当我彻底明白的时候再说吧。
 
呵呵,终于完全的明白了,下面指出一二。
1.一定要明白map[][]的双关性,何为双关?
  (1).map[i][j]表示i到j的距离
  (2).map[i][j]=0表示i到j不可以直接可达
  要达到这种效果,首先将map[][]全部赋值为0,
  然后存储建图,在建图的过程中自然的将直接可达
  的两点赋值为不是0的值了。
2.一定要明白dis[]是干什么用的,是干什么用的呢?
  dis[i]是用来存储要求解的start点到i的最优解的。
  一旦求出,将不会改动。当i=end的时候,也就是得到
  答案的时候。
3.一定要明白visited[]是干什么用的,干什么用的?
 当visited[i]=0,表示i点并没有加入到已经解出的
  集合中,也就是说,下次循环的时候是要访问的对象。
  当visited[i]=1,表示i点已经加入到了解出的集合
  中,下次循环的时候,不能再次访问它了。
好了,就这些了,多了没有,不信你还是不懂!
View Code
#include "iostream"
using namespace std;
char name[201][500];
int map[201][201];  ////用来存储图,map[i][j]用来表示权值,也就是距离了——i到j的距离
int visited[201];  //用来表示某个顶点是否加入到顶点的集合
int dis[201];  //dis[i]用来表示距离——start点到i点的距离
int begin, end, sum;
int Min(int a, int b)
{
    return a>b?b:a;
}
int Str_Int(char name1[]) //将字符串转化成一定的数字
{
    int i;
    for(i=0; i<sum; i++)
        if(strcmp(name1, name[i])==0)
            return i+1;
    strcpy(name[sum++], name1);  
    return sum;
}
int Dijkstra(int n)
{
    memset(visited, 0, sizeof(visited));
    memset(dis, 0, sizeof(dis));
    int now = begin, count = n-1, i;  //count是个细节
    visited[begin] = 1;
    dis[begin] = 999999;  //这个十分的关键哟,不然下面的for循环无法工作
    while(count--)
    {
        int k, maxdistance = 0;
        for(i=1; i<=n; i++)
        {
            if(!visited[i])  //没有加入集合的话,就访问它
            {
                if(map[now][i]!=0)  //两点可以直接到达的话
                    if(dis[i] < Min( dis[now], map[now][i]))
                          //dis[i]不可以比dis[now]更大,但是可以更小,所以用Min
                        dis[i] = Min(,dis[now], map[now][i]);
                if(maxdistance < dis[i])
                    maxdistance = dis[k=i];  //k用来存储距离now最短的顶点
            }
        }
        if(k==end)    break;
        visited[now=k] = 1;  //将k放入集合中,并以k为下一个now,再次寻找下一个距离now最短的顶点
    }
    return dis[end];
}
int main()
{
    int n, r, i, node1, node2, val;
    char name1[200], name2[200];
    char st[200], en[200];
    int k=0;
    while(cin>>n>>r && (n+r))
    {
        k++;
        sum = 0;
        memset(name, 0, sizeof(name));
        memset(map, 0, sizeof(map));
        for(i=0; i<r; i++)
        {
            cin>>name1>>name2>>val;
            node1 = Str_Int(name1);
            node2 = Str_Int(name2);
            map[node1][node2]=map[node2][node1]=val;
        }
        cin>>st>>en;
        begin = Str_Int(st);
        end = Str_Int(en);
        cout<<"Scenario #"<<k<<endl<<Dijkstra(n)<<" tons"<<endl<<endl;
    }
    return 0;
}

 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!