思路:题目是一个最大流问题,可以转化为最短路问题。
#include<iostream>
#include<queue>
#define N 5050
#include<string.h>
#include<algorithm>
#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[N][N],b[N][N];
int ed;
int ed_x[N],ed_y[N],ed_w[N];
bool done[N][N];
long long d[N][N];
struct node{
int x,y;
long long d;
node(int x=0,int y=0,long long d=0){
this->x=x;
this->y=y;
this->d=d;
}
bool operator <(const node &rhs)const{
return d>rhs.d;
}
};
priority_queue<node> Q;
void read(){
int A,B,Q,XI;
scanf("%d%d%d%d%d%d",&n,&m,&A,&B,&Q,&XI);
for (int i=1;i<n;i++)
for (int j=1;j<=m;j++){
XI=(1ll*A*XI+B)%Q;
a[i][j]=XI;
}
for (int i=2;i<=n-1;i++)
for (int j=1;j<m;j++){
XI=(1ll*A*XI+B)%Q;
b[i][j]=XI;
}
}
void getEdge(int x,int y){ //从(x,y)出发点连边
ed=0;
if (x==0){ //起始或终点
if (y==0){ //s
for (int i=1;i<n;i++){
ed++;
ed_x[ed]=i;
ed_y[ed]=1;
ed_w[ed]=a[i][1];
}
}
}else{ //格子节点
//右
ed++;
if (y==m-1){//通向汇点t
ed_x[ed]=0;ed_y[ed]=1;ed_w[ed]=a[x][m];
}else{
ed_x[ed]=x;ed_y[ed]=y+1;ed_w[ed]=a[x][y+1];
}
//左
if (y>1){
ed++;
ed_x[ed]=x;ed_y[ed]=y-1;ed_w[ed]=a[x][y];
}
//下
if (x<n-1){
ed++;
ed_x[ed]=x+1;ed_y[ed]=y;ed_w[ed]=b[x+1][y];
}
//上
if (x>1){
ed++;
ed_x[ed]=x-1;ed_y[ed]=y;ed_w[ed]=b[x][y];
}
}
}
long long solve(){
memset(d,127,sizeof(d));
d[0][0]=0;
memset(done,0,sizeof(done));
Q.push(node(0,0,0));
while (!Q.empty()){
node nd=Q.top();Q.pop();
if (nd.x==0 && nd.y==1) return nd.d;
if (done[nd.x][nd.y])continue;
done[nd.x][nd.y]=true;
d[nd.x][nd.y]=nd.d;
getEdge(nd.x,nd.y);
for (int i=1;i<=ed;i++){
int x=ed_x[i];
int y=ed_y[i];
int w=ed_w[i];
if (d[x][y]>d[nd.x][nd.y]+w){
d[x][y]=d[nd.x][nd.y]+w;
Q.push(node(x,y,d[x][y]));
}
}
}
return 0;
}
int main(){
read();
cout<<solve()<<endl;
return 0;
}
转载这位大神的:https://blog.csdn.net/vcvycy/article/details/78236395