标签:限制 输出 color pst class lang iss ems i++
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 56594 | Accepted: 17083 |
Description
Input
Output
Sample Input
1 4 10000 3 2 2 8000 3 5000 1000 2 1 4 200 3000 2 1 4 200 50 2 0
Sample Output
5250
有限制的最短路题。
首先是建图,设一个源点0,到各点的距离为各点的价值。其余正常建边即可。
由于最后我们要得到1的最短路,所以枚举最短路有效的点的范围。比如1号点等级为lev,那么也就是说在所有最短路的这些点都必须满足在[lev-M,lev+M]这个区间里面。好了,可能你会迫不及待将这个区间作为最后的区间,在想想,如果在这个区间内出现的两个点的他们之间的等级差超过了M值(这是存在的),显然,不符合题意了,所以这个区间还有继续缩小。其实只要稍微动动脑子,就可以找出这样的区间[lev-M,lev],[lev-M+1,lev+1],... ...,[lev,lev+M].然后对spfa做点小调整即可。
#include<cstdio> #include<algorithm> #include<cstring> #include<queue> using namespace std; const int inf=1000000000; int lev[105]; int to[10005]; int w[10005]; int nex[10005]; int head[105]; int cnt=0; void addedge(int uu,int vv,int ww) { to[cnt]=vv;w[cnt]=ww; nex[cnt]=head[uu];head[uu]=cnt++; } int dis[105]; int vis[105]; int main() { int m,n; scanf("%d%d",&m,&n); //建图 memset(head,-1,sizeof(head)); for(int i=1,p,l,x;i<=n;i++) { scanf("%d%d%d",&p,&l,&x); lev[i]=l; addedge(0,i,p); for(int j=1,t,v;j<=x;j++) { scanf("%d%d",&t,&v); addedge(t,i,v); } } int ans=inf; for(int i=0;i<=m;i++)//lev[1]-m+i..lev[1]+i { int low=lev[1]-m+i,high=lev[1]+i; memset(vis,0,sizeof(vis)); for(int i=0;i<=n;i++) dis[i]=inf; queue<int> q; q.push(0); vis[0]=1;dis[0]=0; while(!q.empty()) { int uu=q.front();q.pop(); for(int j=head[uu];j!=-1;j=nex[j]) { int vv=to[j],ww=w[j]; if(lev[vv]>=low&&lev[vv]<=high) { if(dis[vv]>dis[uu]+ww) { dis[vv]=dis[uu]+ww; if(!vis[vv]) { vis[vv]=1; q.push(vv); } } } } } ans=min(ans,dis[1]); } printf("%d\n",ans); return 0; }
标签:限制 输出 color pst class lang iss ems i++
原文地址:https://www.cnblogs.com/acboyty/p/9644128.html