Sicily 1700. Ping

训练的题目

最短路变形

题意:这个题意,太长了,总结回来只有两三句话。输入n表示n个点,从0到n-1,输入m表示m条无向边,输入t,表示终点。要你求起点0到终点t的最短路,不过要先满足一个条件,就是路径的点数不超过10个(包括起点和终点在内 <= 10),如果在10个点内娶不到或者图根本不连通,那么输出no,否则输出最短路

又是一个加了限制的最短路,是要先满足10个点以内再求最短路的,训练的时候就是看错了一直WA。

这题和   poj 1724 ROADS  是一样的题目。可以看作每条边的花费是1点数,你从0出发,手上有9点数,在点数够用的情况下走到终点t的最短路

因此仿照poj这题的代码,写了一个dp,就过了,再仿照写了个bfs搜索,也过了 , 在仿照写了个优先队列+dij , 得到一个MLE,这个是为什么?其实还没想清楚,应该是入队的元素太多(没有加以限制)导致爆了空间,poj那题是100个点,给了64m,这题是1000个点,给了32m,应该是这样了

 

后来上网找到了唯一一个代码,作者的代码写得比我好啊,简单,易懂,附上地址  

http://soj.me/viewsource.php?sid=1796545

 

1.dp的代码

#include <cstdio>

#include <cstring>

#include <vector>

using namespace std;

#define N 1010

#define INF 0x3f3f3f3f

const int lim = 9;



typedef pair<int,int>pii;

vector<pii>e[N];

int d[N][15];



void dfs(int u , int c)

{

   if(d[u][c] != -1) return ;

   d[u][c] = INF;

   int size = e[u].size();

   for(int i=0; i<size; i++)

   {

      pii temp = e[u][i];

      int v = temp.first;

      int w = temp.second;

      if(c-1 >= 0)

      {

         dfs(v,c-1);

         if(d[v][c-1] + w < d[u][c])

            d[u][c] = d[v][c-1] + w;

      }

   }

}



int main()

{

   int n,m,t;

   while(scanf("%d%d%d",&n,&m,&t)!=EOF && n)

   {

      for(int i=0; i<n; i++) e[i].clear();

      while(m--)

      {

         int u,v,w;

         scanf("%d%d%d",&u,&v,&w);

         e[u].push_back( make_pair(v,w) );

         e[v].push_back( make_pair(u,w) );

      }



      memset(d,-1,sizeof(d));

      for(int i=0; i<=lim; i++) d[0][i] = 0;

      int res = INF;

      for(int i=0; i<=lim; i++)

      {

         dfs(t,i);

         if(d[t][i] < res) res = d[t][i];

      }

      if(res == INF) printf("no\n");

      else           printf("%d\n",res);

   }

   return 0;

}

 

 

2.bfs搜索,彻底搜索更新所有状态

#include <cstdio>

#include <cstring>

#include <vector>

#include <queue>

using namespace std;

#define N 1010

#define INF 0x3f3f3f3f

const int lim = 9;



typedef pair<int,int>pii;

vector<pii>e[N];

int d[N][15];



void bfs(int s , int t)

{

   bool inq[N];

   queue<int>q;

   while(!q.empty()) q.pop();

   memset(inq,false,sizeof(inq));

   memset(d,0x3f,sizeof(d));

   for(int i=0; i<=lim; i++) d[s][i]=0;

   inq[s] = true;

   q.push(s);



   while(!q.empty())

   {

      int u = q.front();

      q.pop();

      inq[u] = false;

      int size = e[u].size();

      for(int i=0; i<size; i++)

      {

         pii temp = e[u][i];

         int v = temp.first;

         int w = temp.second;

         int c = 1;

         for(int j=1; j<=lim; j++)

            if(d[u][j-c] + w < d[v][j])

            {

               d[v][j] = d[u][j-c] + w;

               if(!inq[v])

               {

                  inq[v] = true;

                  q.push(v);

               }

            }

      }

   }



   int res = INF;

   for(int i=0; i<=lim; i++)

      if(d[t][i] < res)

         res = d[t][i];

   if(res == INF) printf("no\n");

   else           printf("%d\n",res);

}



int main()

{

   int n,m,t;

   while(scanf("%d%d%d",&n,&m,&t)!=EOF && n)

   {

      for(int i=0; i<n; i++) e[i].clear();

      while(m--)

      {

         int u,v,w;

         scanf("%d%d%d",&u,&v,&w);

         e[u].push_back( make_pair(v,w) );

         e[v].push_back( make_pair(u,w) );

      }

      bfs(0,t);

   }

}

 

3.网上找到的代码

#include <cstdio>

#include <cstring>

#include <vector>

#include <queue>

using namespace std;

#define N 1010

#define INF 0x3f3f3f3f

const int lim = 9;



typedef pair<int,int>pii;

vector<pii>e[N];

int d[N];

int len[N];



void bfs(int s , int t)

{

   bool inq[N];

   queue<int>q;

   while(!q.empty()) q.pop();

   memset(inq,false,sizeof(inq));

   memset(d,0x3f,sizeof(d));

   memset(len,0,sizeof(len));

   d[s] = 0;

   inq[s] = true;

   q.push(s);



   while(!q.empty())

   {

      int u =q.front();

      q.pop();

      inq[u] = false;

      int size = e[u].size();

      for(int i=0; i<size; i++)

      {

         pii temp = e[u][i];

         int v = temp.first;

         int w = temp.second;

         int c = 1;

         if(d[u] + w < d[v])

         {

            d[v] = d[u] + w;

            len[v] = len[u] + c;

            if(len[v] <= lim) q.push(v);

         }

      }

   }



   if(d[t] == INF) printf("no\n");

   else            printf("%d\n",d[t]);

}



int main()

{

   int n,m,t;

   while(scanf("%d%d%d",&n,&m,&t)!=EOF && n)

   {

      for(int i=0; i<n; i++) e[i].clear();

      while(m--)

      {

         int u,v,w;

         scanf("%d%d%d",&u,&v,&w);

         e[u].push_back( make_pair(v,w) );

         e[v].push_back( make_pair(u,w) );

      }

      bfs(0,t);

   }

}

 

你可能感兴趣的:(ping)