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;

}

  

 

你可能感兴趣的:(poj)