P1821 [USACO07FEB] Cow Party S题解
Ratio_Y
·
2024-01-06 18:24:13
·
个人记录
蒟蒻专属 只会朴素dijstra也能过!
题目传送门
首先分析题目,不难看出这是一道要求求最短路的题.
那么,因为数据范围的 1<=n<=1000 ,所以 Floyed 是行不通的,作为一个蒟蒻,剩下能用的只剩Dijstra了。
如果不会堆优化也没关系,我们多开一个数组就好了。
一 变量定义
#include<bits/stdc++.h>
#define fo(x,y,z) for(int (x)=(y);(x)<=(z);(x)++)
#define fu(x,y,z) for(int (x)=(y);(x)>=(z);(x)--)
using namespace std;
const int zhenli=0;//真理义父yyds
const int N=1005;
const int maxx=0x7fffff;
int n,m,x;
int dh[N][N];
int yy[N],fx[N],yz[N],hh[N];
int rm;
$maxx$ 不用多说,**但一定要开大** ~~(才没有因为开小了所以WA呢~~。
$dh$邻接矩阵存初始权值。
$yy$ $fx$ 分别存由 $x$ 出发和到 $x$ 的最小值。
$yz$ 作判断标记,$hh$ 存最终路径,$rm$ 为中间量
------------
# 二 主体结构
输入,初始化等不用过多赘叙。
```
fo(i,1,n)
if(dh[x][i]<maxx)yy[i]=dh[x][i];
fo(i,1,n)
if(dh[i][x]<maxx)fx[i]=dh[i][x];
warm(x);
wazl(x);
```
关键在于dij的函数部分。
我们大多牢记了dij的板子。
那么,多打一个不就好了吗。
只是注意,第二个函数中,赋初始值时是反向的。
```
void warm(int x)
{
int y;
yz[x]=1;
fo(i,1,n-1)
{
rm=maxx;
fo(j,1,n)
if(yz[j]==0&&yy[j]<rm)
{
y=j;
rm=yy[j];
}
yz[y]=1;
fo(j,1,n)
if(yz[j]==0&&yy[j]>yy[y]+dh[y][j])
yy[j]=yy[y]+dh[y][j];
}
}
void wazl(int x)
{
int z;
memset(yz,0,sizeof yz);
yz[x]=1;
fo(i,1,n-1)
{
rm=maxx;
fo(j,1,n)
if(yz[j]==0&&fx[j]<rm)
{
z=j;
rm=fx[j];
}
yz[z]=1;
fo(j,1,n)
if(yz[j]==0&&fx[j]>fx[z]+dh[j][z])
fx[j]=fx[z]+dh[j][z];
}
}
```
------------
# 最后 整合起来 完工
完整代码如下:
```
#include<bits/stdc++.h>
#define fo(x,y,z) for(int (x)=(y);(x)<=(z);(x)++)
#define fu(x,y,z) for(int (x)=(y);(x)>=(z);(x)--)
using namespace std;
const int zhenli=0;
const int N=1005;
const int maxx=0x7fffff;
int n,m,x;
int dh[N][N];
int yy[N],fx[N],yz[N],hh[N];
int rm;
void warm(int x)
{
int y;
yz[x]=1;
fo(i,1,n-1)
{
rm=maxx;
fo(j,1,n)
if(yz[j]==0&&yy[j]<rm)
{
y=j;
rm=yy[j];
}
yz[y]=1;
fo(j,1,n)
if(yz[j]==0&&yy[j]>yy[y]+dh[y][j])
yy[j]=yy[y]+dh[y][j];
}
}
void wazl(int x)
{
int z;
memset(yz,0,sizeof yz);
yz[x]=1;
fo(i,1,n-1)
{
rm=maxx;
fo(j,1,n)
if(yz[j]==0&&fx[j]<rm)
{
z=j;
rm=fx[j];
}
yz[z]=1;
fo(j,1,n)
if(yz[j]==0&&fx[j]>fx[z]+dh[j][z])
fx[j]=fx[z]+dh[j][z];
}
}
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
scanf("%d%d%d",&n,&m,&x);
fo(i,1,n)
fo(j,1,n)
dh[i][j]=maxx;
memset(yy,0x3f,sizeof yy);
memset(fx,0x3f,sizeof fx);
fo(i,1,m)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(c<dh[a][b])dh[a][b]=c;//重边取短
}
fo(i,1,n)
if(dh[x][i]<maxx)yy[i]=dh[x][i];
fo(i,1,n)
if(dh[i][x]<maxx)fx[i]=dh[i][x];
warm(x);
wazl(x);
fo(i,1,n)
if(i!=x)
{
hh[i]=yy[i]+fx[i];
}
sort(hh+1,hh+n+1,cmp);
printf("%d",hh[1]);
return zhenli;
}
```
(我是食月的天狗$Qwq$。