bzoj1375[Baltic2002]Bicriterial routing 雙調路徑

分層圖,dp。本題求的是多少種方案,不是多少個路徑。。。

dp[i][j]表示到第i點時用了j時間所花的錢數。

注意:走過最長的路徑是(n-1)*100,否則會爆!!!

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<algorithm>
using namespace std;
#define inf 2050
typedef long long ll;
int n,m,s,e;
int maxn;
struct node
{
	int to,next,len,val;
}edge[2050];
int head[1000];
int cnt;
void add(int f,int t,int l,int v)
{
	edge[cnt].to=t;
	edge[cnt].len=l;
	edge[cnt].val=v;
	edge[cnt].next=head[f];
	head[f]=cnt++;
}
struct nn
{
	int mon,sum;
}dp[105][10005];
struct mm
{
	int pos,dis;
};
queue<mm>Q;
int vis[105][10005];
int min_val=0x3f3f3f3f;
int ans;
void dij()
{
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<=30005;j++)
		{
			dp[i][j].mon=0x3f3f3f3f;
			dp[i][j].sum=0;
		}
	}
	dp[s][0].mon=0;
	dp[s][0].sum=1;
	vis[s][0]=1;
	mm st;
	st.pos=s;
	st.dis=0;
	Q.push(st);
	while(!Q.empty())
	{
		mm u=Q.front();
		Q.pop();
		vis[u.pos][u.dis]=0;
		for(int i=head[u.pos];i!=-1;i=edge[i].next)
		{
			if(u.dis+edge[i].len>maxn+1)continue;
			if(dp[u.pos][u.dis].mon+edge[i].val<dp[edge[i].to][u.dis+edge[i].len].mon)
			{
				dp[edge[i].to][u.dis+edge[i].len].mon=dp[u.pos][u.dis].mon+edge[i].val;
				dp[edge[i].to][u.dis+edge[i].len].sum=1;
				if(vis[edge[i].to][u.dis+edge[i].len]==0)
				{
					mm vv;
					vv.pos=edge[i].to;
					vv.dis=u.dis+edge[i].len;
					vis[edge[i].to][u.dis+edge[i].len]=1;
					Q.push(vv);
				}
			}
		}
	}
}
int main()
{
	scanf("%d %d %d %d",&n,&m,&s,&e);
	memset(head,-1,sizeof(head));
	for(int i=1;i<=m;i++)
	{
		int a,b,c,d;
		scanf("%d %d %d %d",&a,&b,&c,&d);
		add(a,b,c,d);
		add(b,a,c,d);
	}
	maxn=(n-1)*100;
	dij();
	for(int i=0;i<=maxn+5;i++)
	{
		if(!dp[e][i].sum)continue;
		if(dp[e][i].mon<min_val)//時間長但錢數少
		{
			ans++;
			min_val=dp[e][i].mon;
		}
	}
	printf("%d",ans);
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章