poj 1062
题意上有一点要注意:在任何一条路径上,任何两点的等级之差都必须在限制之内。比如说:a、b、c的等级分别为3、2、1,限制为1的话。能和a、b交易就不能和c交易了,因为a和c超出限制。同样,b、c能交易就不能和a交易了,因为a、c任然超出限制。根据题意将每种物品看成每个顶点,优惠价格看成边,便构成一有向图,然后可以用Dijkstra求解。因为有等级限制,求一次Dijkstra是不行的。我看了网上大牛的思想:枚举0~L的每一种限制i,除去不在区间[rand[1]-i,rand[i]+m-i](rand[1]为酋长的等级)的顶点,然后Dijkstra,取其中最小的。
#include<iostream>
#include<vector>
using namespace std;
#define MAX_INT 1234567890
struct edge
{
int v;
int value;
};
struct good
{
int price;
int grade;
};
good head[101];
vector <edge> map[101];
int dist[101],visit[101];
bool flag[101];
int dijkstra(int n)
{
int i,j,k,min;
for(i=1;i<=n;i++)
dist[i]=MAX_INT;
for(i=0;i<map[1].size();i++)
if(flag[map[1][i].v])
dist[map[1][i].v]=map[1][i].value;
visit[1]=1;
for(i=1;i<n;i++)
{
min=MAX_INT; k=0;
for(j=1;j<=n;j++)
if(!visit[j] && dist[j]<min)
{
min=dist[j];
k=j;
}
visit[k]=1;
if(k==0) break;
for(j=0;j<map[k].size();j++)
{
if(!visit[map[k][j].v] && flag[map[k][j].v])
{
if(dist[map[k][j].v]>dist[k]+map[k][j].value)
dist[map[k][j].v]=dist[k]+map[k][j].value;
}
}
}
min=MAX_INT; dist[1]=0;
for(i=1;i<=n;i++)
{
if(min>dist[i]+head[i].price)
min=dist[i]+head[i].price;
}
return min;
}
int main()
{
int i,j,m,n,k,gap,min;
edge e;
while(cin>>gap>>n)
{
for(i=1;i<=n;i++)
{
cin>>head[i].price>>head[i].grade>>m;
for(j=0;j<m;j++)
{
cin>>e.v>>e.value;
map[i].push_back(e);
}
}
min=MAX_INT;
for(i=0;i<=gap;i++)
{
memset(visit,0,sizeof(visit));
for(j=1;j<=n;j++)
if(head[j].grade>=head[1].grade-i && head[j].grade<=head[1].grade+gap-i)
flag[j]=true;
else
flag[j]=false;
k=dijkstra(n);
if(min>k) min=k;
}
cout<<min<<endl;
for(i=1;i<=n;i++)
map[i].clear();
}
return 0;
}
看了大牛的思想任然感觉有点模糊,所以我有用dfs做了一遍,这样做简单一点,也可以AC。
#include<iostream>
#include<cstring>
using namespace std;
#define MAX_INT 1234567890
int edge[101][101],price[101],rank[101],visit[101],min1,n,gap;
int dfs(int i,int value,int min_rank,int max_rank)
{
int j;
visit[i]=1;
min1=(min1>value+price[i])? value+price[i]:min1;
for(j=1;j<=n;j++)
{
if(!visit[j] && edge[i][j])
{
if(rank[j]<min_rank && max_rank-rank[j]<=gap)
dfs(j,value+edge[i][j],rank[j],max_rank);
else if(rank[j]>max_rank && rank[j]-min_rank<=gap)
dfs(j,value+edge[i][j],min_rank,rank[j]);
else if(rank[j]>=min_rank && rank[j]<=max_rank)
dfs(j,value+edge[i][j],min_rank,max_rank);
}
}
visit[i]=0;
return 0;
}
int main()
{
int i,j,s,t,num;
while(cin>>gap>>n)
{
for(i=1;i<=n;i++)
{
cin>>price[i]>>rank[i]>>num;
for(j=0;j<num;j++)
{
cin>>s>>t;
edge[i][s]=t;
}
}
min1=MAX_INT;
memset(visit,0,sizeof(visit));
dfs(1,0,rank[1],rank[1]);
cout<<min1<<endl;
}
return 0;
}
浙公网安备 33010602011771号