POJ 1847 dijstra算法

POJ 无限循环CE中。感觉是读题难。然后就可以建图上模板了。

附个人代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#define maxn 0x1f1f1f1f
#define size 210
using namespace std;

int low[size];
bool used[size];
int map[size][size];
int n, a, b;

void init()
{
    for (int i=0; i<=n; ++i)
    {
        for (int j=0; j<=n; ++j)
        map[i][j] = maxn;
    }
    memset(used, 0, sizeof(used));
}

void dijkstra(int aa)
{
    int i, j, k;
    for (i=0; i<n; ++i)
    low[i] = map[aa][i];
    low[aa] = 0;
    used[aa] = true;
    for (i=0; i<n; ++i)
    {
        int min = maxn;
        int temp;
        for (j=0; j<n; ++j)
        {
            if (used[j] == 0 && low[j] < min)
            {
                min = low[j];
                temp = j;
            }
        }
        if (min == maxn) break;
        used[j] = 1;
        for (j=0; j<n; ++j)
        {
            if (used[j] == 0 && low[j] > low[temp] + map[temp][j])
            {
                low[j] = low[temp] + map[temp][j];
            }
        }
    }
}

int main()
{
    while(~scanf("%d%d%d", &n, &a, &b))
    {
        init();
        a--;
        b--;
        for (int i=0; i<n; ++i)  //第i个节点的信息
        {
            int t, tt;
            scanf("%d", &t);  //有t个节点直接相连
            for (int j=0; j<t; ++j)  // 输入t个节点
            {
                scanf("%d", &tt);
                tt--;
                if (j == 0)  //第一个为默认方向
                {
                    //map[tt][i] = 0;
                    map[i][tt] = 0;
                }
                else
                {
                    //map[tt][i] = 1;
                    map[i][tt] = 1;
                }
            }
        }
        dijkstra(a);
        printf("%d\n", (low[b] == maxn) ? -1 : low[b]);
    }
    return 0;
}
附标准代码:

#include<iostream>
#include<cstdio>
  #include<cstring>
  using namespace std;
  #define N 105
  #define max 0xfffffff
  int f[N],mark[N],p[N][N];
  int n,a,b;
  void Dijkstra()
 {
     int i,j,k,min;
     memset(mark,0,sizeof(mark));
     for(i=1;i<=n;i++)
         f[i]=p[a][i];
     f[a]=0;
     mark[a]=1;
     for(i=1;i<=n;i++)
     {
         min=max;
         for(j=1;j<=n;j++)
         {
             if(!mark[j]&&f[j]<min)
             {
                 min=f[j];
                 k=j;
             }
         }
         if(min==max) break;
         mark[k]=1;
         for(j=1;j<=n;j++)
         {
             if(!mark[j]&&f[k]+p[k][j]<f[j])
                 f[j]=f[k]+p[k][j];
         }
     }
     if(f[b]==max)   printf("-1\n");
     else
         printf("%d\n",f[b]);
 }
 int main()
 {
     int i,j;
     while(scanf("%d%d%d",&n,&a,&b)!=EOF)
     {
         int c;
         for(i=1;i<=n;i++)
             for(j=1;j<=n;j++)
                 p[i][j]=max;
         for(i=1;i<=n;i++)
         {
             scanf("%d",&c);
             if(c==0)  continue;//第一次的时候忘了考虑c的取值,所以Time Limit Exceeded了一次
             int d;
             scanf("%d",&d);
             p[i][d]=0;
             c-=1;
             while(c--)
             {
                 scanf("%d",&d);
                 p[i][d]=1;
             }
         }
         Dijkstra();
     }
     return 0;
 }

时间: 2024-11-10 07:41:39

POJ 1847 dijstra算法的相关文章

POJ 1847 Floyd_wshall算法

前面用dijstra写过了.但是捏.数据很小.也可以用Floyd来写. 注意题目里给出的是有向的权值. 附代码:#include<stdio.h>#include<string.h>#include<iostream>#define inf 0x1f1f1f1fusing namespace std; int n, a, b;int num;int dis[210][210];int i, j, k; int main(){    while (cin >>

POJ 1379 模拟退火算法

求规定平面上一点到已知点的最小距离最大的点. 模拟退火的流程是,随机构造几组解作为初始解空间,每次对当前解空间进行随机扩展,若发现更优解则替换. 进行的次数由参数人为控制,而随机扩展的幅度也是随着次数逐渐减小的. #include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<cmath> #include<string> #include&

poj 1847 最短路简单题,dijkstra

1.poj  1847  Tram   最短路 2.总结:用dijkstra做的,算出a到其它各个点要改向的次数.其它应该也可以. 题意: 有点难懂.n个结点,每个点可通向ki个相邻点,默认指向第一个相邻点,可以改变指向.求一条从A到B的路,使用最少改变路上点的指向的次数. #include<iostream> #include<cstring> #include<cmath> #include<queue> #include<algorithm>

单源最短路Dijstra算法

Dijstra算法是寻找从某一顶点i出发到大其他顶点的最短路径.Distra算法的思想与Prim算法很像,它收录顶点的规则是按照路径长度递增的顺序收录的.设v0是源顶点,我们要寻找从v0出发到其他任意一点的最短路径.设已经求解的顶点(已经找到从v0出发到达该顶点最短路径的顶点)组成的集合是S={v0,v1,...vk};在收录下一个顶点v的时候要么是(v0,v),要么是(v0,vj,v);如果是后者,则一定有vj∈S,这一点很容易用反正法证明.Dijstra算法的时间复杂度是O(V^2),若是稀

POJ 1847 Tram 单源最短路径

题意:轨道网,有若干转换器,每个转换器都和其他若干转换器相连,转换器初始指向第一个与其相连的转换器.问要到达终点需要最少转换多少次? 思路:可以用dijkstra单源最短路来做,把轨道网看做有向图(因为1第一个指向2,2的第一个不一定指向1),当前转换器处始指向的那个转换器之间的路径权值为0,其他路径权值为1,求一次起点到终点的最短路,结果就是最少转换次数,注意可能没有路径,这时要输出-1 代码: /* poj 1847 264K 0MS */ #include<cstdio> #includ

poj 2253 dijstra变形

dijstra算法的变形,定义:dist[i]为源点到点i的若干路径上的边的最大值的最小值,然后会发现可以用和dijstra一样的贪心方法,当前dist最小的以后都不会再被更新. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <cmath> 5 using namespace std; 6 7 const int INF = 9999999; 8 const

POJ 2485(Kruskal算法)

第一道Kruskal算法题 #include <iostream>#include <algorithm>#include <cstdio>using namespace std;#define max 505int f[max],maxw;struct edge{    int st,en,w;}ed[max*max/2]; int  find(int k){    if(k!=f[k])f[k]=find(f[k]);    return f[k];}void co

POJ 1847 Tram 【最短路,spfa算法,题意理解是关键呀!!】

Tram Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 13468   Accepted: 4954 Description Tram network in Zagreb consists of a number of intersections and rails connecting some of them. In every intersection there is a switch pointing to t

POJ 1797 kruskal 算法

题目链接:http://poj.org/problem?id=1797 开始题意理解错.不说题意了. 并不想做这个题,主要是想测试kruskal 模板和花式并查集的正确性. 已AC: /* 最小生成树 kruskal算法 过程:每次选取没有参与构造最小生成树并且加入之后不会构成回路的边中权值最小的一条 作为最小生成树的一条新边.直至选择了V-1条边. */ #include <stdio.h> #include <string.h> #include <iostream>