把联通每个农田最小的花费放在p[]里,要是联通的花费比挖井大就直接挖井,要是最后发现一口井都没挖,就找挖一口井的花费和联通它的花费差最小的,因为如果挖井价格比联通它小,那前面就会确定是挖井而不是联通了,所有这里差最小就代表多花钱最少的做法,#1#8过了,别的都wa
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 3e5 + 10;
int p[N];
int nt[400][400];
int sj[400];
int bj[400];
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
p[i] = N;
cin >> sj[i];
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cin >> nt[i][j];
}
}
for (int i=0; i < n; i++)
{
int t = -1;
for (int j = 0; j < n; j++)
{
if (nt[i][j]!=0&&!bj[j] && (t == -1 || p[t] > p[j]))
{
t = j;
}
}
if (t == -1)continue;
bj[t] = 1;
for (int j = 0; j < n; j++)
{
if(nt[t][j]!=0)p[j] = min(p[j], nt[t][j]);
}
}
int minn=N;
int flag = 0;
for (int i = 0; i < n; i++)
{
minn = min(minn, abs(p[i] - sj[i]));
p[i] = min(p[i], sj[i]);
if (p[i] == sj[i])flag = 1;
}
int ans = 0;
for (int i = 0; i < n; i++)
{
ans += p[i];
}
if (flag)cout << ans << endl;
else cout << ans + minn;
return 0;
}