贪心思路:按边权从小达到排序,依次选取 如果这个边起点被选过了 不能选,如果这个边的双向边被选过了,不能选,如果这个边选了会构成环,不能选。 结果错了两个点,请大神帮忙看看什么原因。。
//贪心思路:按边权从小达到排序,依次选取
//如果这个边起点被选过了 不能选,如果这个边的双向边被选过了,不能选,如果这个边选了
//会构成环,不能选。
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int N=1005;
struct E{//存边
int from,to,v;
E(int a=0,int b=0,int c=0):from(a),to(b),v(c){}
} a[N];
bool cmp(E x,E y){
return x.v<y.v;
}
bool f[25]={0};
vector<int> v[25];
bool c[25];
int b[25][25]={0};
bool dfs(int x,int y){
if(x==y) return true;
//cout<<x<<endl;
for(int i=0;i<v[x].size();i++){
if(c[v[x][i]]) continue;
c[v[x][i]]=true;
if(dfs(v[x][i],y)) return true;
}
return false;
}
bool check(int x,int y){
memset(c,false,sizeof(c));
if(dfs(y,x) )
return false;
return true;
}
int main(){
int n,k,x,cnt=0,ans=0;
cin>>n>>k;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>b[i][j];
x=b[i][j];
if(i==j) continue;
a[cnt++]=E(i,j,x);
}
}
sort(a,a+cnt,cmp);
k=n-k;
for(int i=0;i<cnt;i++){
// cout<<a[i].from<<' '<<a[i].to<<endl;
if(f[a[i].from]) continue;
// cout<<"a"<<endl;
if(b[a[i].from][a[i].to]==-1) continue;
// cout<<"b"<<endl;
if(!check(a[i].from,a[i].to)) continue;
// cout<<"c"<<endl;
b[a[i].from][a[i].to]=-1;
b[a[i].to][a[i].from]=-1;
f[a[i].from]=true;
v[a[i].from].push_back(a[i].to);
ans+=a[i].v;
k--;
if(!k) break;
}
cout<<ans;
return 0;
}