poj 3411 Paid Roads 夜

http://poj.org/problem?id=3411

题目大意:

n城市 m条路(可能重)

每条路两种情况付费 a b c p r

如果已经经过了c城则可以付费p 否则只能付费r

求从1到n最小花费

思路:

记录各种花费 然后Dfs枚举 但是本题某一点可以多次

不过由于边的数量是最多10 所以某一个点最多经过4此(自己想吧 亲!)

快乐深搜 注意n=1的情况

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<algorithm>
#include<set>

using namespace std;

const int N=11;
const int M=1000000;
struct node
{
   bool can;
   int cp[N];
   int cr;
}road[N][N];
int had[N];
int n,m;
int ans;
void begin()
{
    for(int i=1;i<=n;++i)
    for(int j=1;j<=n;++j)
    {
        road[i][j].can=false;
        road[i][j].cr=M;
        for(int l=1;l<=n;++l)
        {
            road[i][j].cp[l]=M;
        }
    }

}
void Dfs(int a,int sum)
{
    for(int b=1;b<=n;++b)
    {
        if(had[b]<n&&road[a][b].can==true)
        {
            int temp=road[a][b].cr;
            for(int l=1;l<=n;++l)
            {
                if(had[l]&&road[a][b].cp[l]<temp)
                temp=road[a][b].cp[l];
            }
            if(b==n)
            {
                ans=min(ans,sum+temp);
            }else if(sum+temp<ans)
            {
                ++had[b];
                Dfs(b,sum+temp);
                --had[b];
            }
        }
    }
}
int main()
{

   while(scanf("%d %d",&n,&m)!=EOF)
   {
       begin();
       while(m--)
       {
           int a,b,c,p,r;
           scanf("%d %d %d %d %d",&a,&b,&c,&p,&r);
           road[a][b].can=true;
           road[a][b].cp[c]=min(road[a][b].cp[c],p);
           road[a][b].cr=min(road[a][b].cr,r);
       }
       if(n==1)
       {
           printf("0\n");
           continue;
       }
       ans=M;
       memset(had,0,sizeof(had));
       had[1]=1;
       Dfs(1,0);
       if(ans==M)
       printf("impossible\n");
       else
       printf("%d\n",ans);
   }
   return 0;
}

  

原文地址:https://www.cnblogs.com/liulangye/p/2594844.html