这道题比较思维
从代数上的限制转化为图论上的限制
1~n的一条路就代表一种 sum X * C的情况,X就代表选与不选,权值为C
最小化sum就相当于求最短路。
但这题更坑的是还有一种最小环的情况。因为是说了1的出度为1,n的入度为1,但是没说1的入读和n的出度限制。
从起点出发的最小环? 站在最短路的基础上,从s —— i的最短路+ g[i, s]
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int N = 310;
int n;
int C[N][N];
int dist[N], vis[N];
int SPFA(int s)
{
queue<int> q;
memset(vis, 0, sizeof vis);
memset(dist, inf, sizeof dist);
q.push(s);
dist[s] = 0, vis[s] = 1;
while (!q.empty())
{
int t = q.front(); q.pop();
vis[t] = 0;
for (int i = 1; i <= n; i++)
{
if (dist[i] > dist[t] + C[t][i])
{
dist[i] = dist[t] + C[t][i];
if (!vis[i])
{
q.push(i);
vis[i] = 1;
}
}
}
}
int ans = inf;
for (int i = 1; i <= n; i++)
{
if (i == s) continue;
ans = min(ans, dist[i] + C[i][s]);
}
return ans;
}
int main()
{
while (cin >> n)
{
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
scanf("%d", &C[i][j]);
int r1 = SPFA(1);
int ans = dist[n];
int rn = SPFA(n);
printf("%d\n", min(ans, r1 + rn));
}
return 0;
}