poj 1729

来源:互联网 发布:多益网络老板广州首富 编辑:程序博客网 时间:2024/06/18 00:05

大致题意:给定的n个点,以及n个点之间的m条路,每条路有话费和长度,让你在不超过给定花费的条件下找到从1到n的最短的距离!

思路:搜索,首先直接深搜肯定是要超时的,有两个剪枝的方法:

1、搜索的某点时,如果该点到终点的最小花费加上已经花的超过k,则直接跳出!

2、搜索的某点时,如果该点到终点的距离加上已经走过的距离大于已经找到的最小值,跳出!

下面是代码:

#include<iostream> #include<string>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<queue>#include<stack>#include<vector>#include<climits>using namespace std; #define rep(i,n) for(i=0; i<(n); i++)#define repf(i,n,m) for(i=(n); i<=(m); i++)//正循环的#define repd(i,n,m) for(i=(n); i>=(m); i--) //负循环的 #define fab(a) (a)>0?(a):0-(a)#define max(a,b) (a)>(b)?(a):(b)#define min(a,b) (a)<(b)?(a):(b)#define ll __int64#define arc(a) (a)*(a)#define inf 1000000   //最大值的#define exp 0.0000001     //浮点型的#define N  105   //记录开的数组int pre[N];int length=INT_MAX;struct pp{    int pre,y,len,cost;}b[N*100];//代表的是路的 int k,n,m,len;int cost[N];int dis[N];int mincost[N],mindis[N];bool flag[N]; void addpage(int s,int d,int l,int t){    b[len].y=d;    b[len].len=l;    b[len].cost=t;    b[len].pre=pre[s];    pre[s]=len++;} void find(int s){    int i,j;    queue<int>q;    bool vis[N];    memset(vis,false,sizeof(vis));    vis[s]=true;    q.push(s);    while(!q.empty())    {        int y=q.front();        q.pop();        vis[y]=false;  //      printf("  %d\n",y);        for(i=pre[y];i!=-1; i=b[i].pre)        {            j=b[i].y;      //      printf("%d\n",j);            if(dis[j]>dis[y]+b[i].len)            {                dis[j]=dis[y]+b[i].len;                if(vis[j]==false)                {                    q.push(j);                    vis[j]=true;                }            }        }    }    vis[s]=false;}void find1(int s){    int i,j;    queue<int>q;    bool vis[N];    memset(vis,false,sizeof(vis));    vis[s]=true;    q.push(s);    while(!q.empty())    {        int y=q.front();        q.pop();        vis[y]=false;        for(i=pre[y];i!=-1; i=b[i].pre)        {            j=b[i].y;            if(cost[j]>cost[y]+b[i].cost)            {                cost[j]=cost[y]+b[i].cost;                if(vis[j]==false)                {                    q.push(j);                    vis[j]=true;                }            }        }    }    vis[s]=true;}void dfs(int s,int len,int p){    if(s==n)    {        if(p<=k)         length=min(len,length);        return ;    }    int i,y,j;    flag[s]=true;    for(i=pre[s];i!=-1; i=b[i].pre)    {        y=b[i].y;        if(p+mincost[y]+b[i].cost>k || len+b[i].len+mindis[y]>length)         continue;         dfs(y,len+b[i].len,p+b[i].cost);    }    flag[s]=false;}int main(){    int i,j;    int s,d,l,t;    while(~scanf("%d",&k))    {        scanf("%d%d",&n,&m);        len=1;        memset(pre,-1,sizeof(pre));         repf(i,1,m)        {            scanf("%d%d%d%d",&s,&d,&l,&t);            addpage(s,d,l,t);        }         repf(i,1,n)        {            repf(j,1,n)             {                cost[j]=dis[j]=inf;             }             dis[i]=0;             find(i);            mindis[i]=dis[n];     //      printf("%d\n",mindis[i]);                         cost[i]=0;            find1(i);            mincost[i]=cost[n];        //    printf("%d\n",mincost[i]);       //     system("pause");        }        memset(flag,false,sizeof(flag));        length=inf;        dfs(1,0,0);        printf("%d\n",length);    }    return 0;} 


原创粉丝点击