(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦
目录
题意:传送门
原题目描述在最下面。
给你一个矩阵
C
C
,你自己选择一个只含的矩阵
X
X
,求最小值。
不过矩阵
X
X
是有限制条件的,。
思路:
经过大佬的解释,这就变成了一个起点出度为1,终点入度为1,其他点出度等于入度的图。
然后大佬说这题答案肯定是
min(dis1,1+disn,n,dis1,n)
m
i
n
(
d
i
s
1
,
1
+
d
i
s
n
,
n
,
d
i
s
1
,
n
)
。
这里
dis1,1
d
i
s
1
,
1
指的是从1出发的非自环闭环最小值,
dis1,n
d
i
s
1
,
n
指的是最短路。
- 非自环闭环最短路的求法:spfa时把与起点相邻的点加入队列,
dis[i]=ar[start][i],vis[i]=1,dis[start]=INF,vis[start]=0
d
i
s
[
i
]
=
a
r
[
s
t
a
r
t
]
[
i
]
,
v
i
s
[
i
]
=
1
,
d
i
s
[
s
t
a
r
t
]
=
I
N
F
,
v
i
s
[
s
t
a
r
t
]
=
0
。然后跑spfa就行了。
AC代码:
#include<bits/stdc++.h>
#define fuck(x) cout<<"* "<<x<<"\n"
using namespace std;
typedef long long LL;
const int N = 3e2+5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int n,m;
int ar[N][N],dis[N],vis[N];
void dij(int st,int ed){
queue<int>Q;
for(int i=1;i<=n;++i){
if(i!=st){
dis[i] = ar[st][i];
vis[i] = 1;
Q.push(i);
}else{
dis[i] = INF;
vis[i] = 0;
}
}
while(!Q.empty()){
int u = Q.front();Q.pop();
vis[u] = 0;
for(int i = 1; i<= n; ++i){
if(dis[i]>dis[u]+ar[u][i]){
dis[i]=dis[u]+ar[u][i];
if(vis[i]<=1){
vis[i]=1;
Q.push(i);
}
}
}
}
}
int main(){
while(~scanf("%d",&n)){
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
scanf("%d",&ar[i][j]);
}
}
dij(1,n);
int s1 = dis[1], s2 = dis[n];
dij(n,n);
s1+=dis[n];
printf("%d\n", min(s1,s2));
}
return 0;
}