版权声明:虽然本蒟蒻很菜,但各位dalao转载请注明出处谢谢。 https://blog.csdn.net/xuxiayang/article/details/89602087
给定到达别的数字的代价,求从第一行的数字到最后一行的数字的最大剩余代价
数据范围:
呀QWQ
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
using namespace std;int n,map[501][501],dis[25001],Ans=-0x3f3f3f3f,p,xl,f[2051][2051];
const int dx[4]={-1,0,1,0};
const int dy[4]={0,1,0,-1};
inline int read()
{
char c;int f=0,d=1;
while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;
while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
return d*f;
}
signed main()
{
memset(f,0x3f,sizeof(f));
n=read();p=read();xl=read();
for(register int i=1;i<=p;i++) dis[i]=read(),f[i][i]=0;
for(register int i=1;i<=n;i++) for(register int j=1;j<=n;j++) map[i][j]=read();
for(register int i=1;i<=n;i++)
for(register int j=1;j<=n;j++)
{
int ys=map[i][j];
for(register int k=0;k<4;k++)
{
int nx=i+dx[k],ny=j+dy[k],nys=map[nx][ny];
if(nx<1||nx>n||ny<1||ny>n||ys==nys) continue;
f[ys][nys]=min(f[ys][nys],dis[nys]);
}
}
for(register int k=1;k<=p;k++)
for(register int i=1;i<=p;i++)
for(register int j=1;j<=p;j++)
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
for(register int i=1;i<=n;i++)
for(register int j=1;j<=n;j++)
Ans=max(Ans,xl-f[map[1][i]][map[n][j]]-dis[map[1][i]]);
if(Ans<1) return puts("NO");
printf("%d",Ans);
}
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstring>
#define id(x,y) (x-1)*n+y
#define LL long long
#define from_ys map[i][j]
#define to_ys map[i+dx[k]][j+dy[k]]
#define tox i+dx[k]
#define toy j+dy[k]
using namespace std;int n,map[51][51],dis[2501],ans[2501],xl,p,l[2501],tot,Ans=-0x3f3f3f3f;
bool check[2501],vis[2501];
struct node{int next,to,w;}e[12500001];
inline void add(int u,int v,int w){e[++tot]=(node){l[u],v,w};l[u]=tot;return;}
const int dx[4]={-1,0,1,0};
const int dy[4]={0,1,0,-1};
inline LL read()
{
char c;int f=0,d=1;
while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;
while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
return d*f;
}
inline void spfa(int S)
{
memset(ans,0x3f,sizeof(ans));
memset(vis,0,sizeof(vis));
check[map[1][S]]=true;
queue<int>q;
q.push(S);ans[S]=dis[map[1][S]];vis[S]=true;
while(q.size())
{
int x=q.front();q.pop();
for(register int i=l[x];i;i=e[i].next)
{
int y=e[i].to,w=e[i].w;
if(ans[y]>ans[x]+w)
{
ans[y]=ans[x]+w;
if(!vis[y]) vis[y]=true,q.push(y);
}
}
vis[x]=false;
}
for(register int i=1;i<=n;i++) Ans=max(Ans,xl-ans[id(n,i)]);
return;
}
signed main()
{
n=read();p=read();xl=read();
for(register int i=1;i<=p;i++) dis[i]=read();
for(register int i=1;i<=n;i++) for(register int j=1;j<=n;j++) map[i][j]=read();
for(register int i=1;i<=n;i++)
for(register int j=1;j<=n;j++)
{
for(register int k=0;k<4;k++) if(from_ys!=to_ys&&tox>0&&tox<=n&&toy>0&&toy<=n) add(id(i,j),id(tox,toy),dis[to_ys]);
for(register int k=1;k<=n;k++)
for(register int l=1;l<=n;l++)
if(map[i][j]==map[k][l]&&(i!=k||j!=l))
add(id(i,j),id(k,l),0);
}
for(register int i=1;i<=n;i++) if(!check[map[1][i]]) spfa(i);
if(Ans<1) return puts("NO")&0;
printf("%d",Ans);
}