Title Description
Boring stuff at home in the countryside, like farming. There farmland n blocks, numbered from 1 ~ n. To irrigation farming
As we all know stuff is a magician, he can consume a certain MP in his magic on a field so that the Yellow River water to the sky. He can also consume a certain amount of MP portal established in the two drainage fields, making this piece of Tian Tian drinking water with water. (1 <= n <= 3e2)
Heaven Yellow River water consumption is Wi, i is the number of farmland (1 <= Wi <= 1e5)
Established consumption portal is Pij, i, j is the number of farmland (1 <= Pij <= 1e5, Pij = Pji, Pii = 0)
Stuff for all the fields of irrigation minimum consumption
Enter a description
Line 1: a number n
Row 2 to row n + 1: a number wi
N + 2 th row to row 2n + 1: Matrix Matrix i.e. pij
Output Specifications
MP minimum consumption value stuff
Sample Input
4
5
4
4
3
0 2 2 2
2 0 3 3
2 3 0 4
2 3 4 0
Sample Output
9
Thinking
Each farm will imagine a point between the two points and water consumption can be considered as caused by the MP weighted edges between two points, so that a farm becomes weighted FIG. The next question is how to deal with this heavenly water consumption, we will be seen as a super day origin, it also points to the weighting of farmland side, namely diversion MP consumption. To make it possible to irrigate all the farmland and consume the least, the problem can be transformed into a problem to find the minimum spanning tree in a weighted graph, so the next question is how to find its minimum spanning tree in the graph we create.
Kruskal's algorithm used here, all the edges are sorted according to weight, by weight in ascending order to examine the sides, if not in the same end side of the set, where they merge the two collections (disjoint-set may be employed), while select the side edges until the selected n (with n + 1 points), the selected edge may form a minimum spanning tree of the graph, which weights are summed to minimizing the consumption of MP.
Code
#include <iostream>
#include<algorithm>
using namespace std;
const int size=1e5;
struct Edge{
int s,t,value;
bool operator<(Edge&b){
return value<b.value;
}
}edge[size];
int par[size];
void ini(int n)
{
for(int i=0;i<=n;i++)
par[i]=i;
}
int find(int n)
{
return par[n]==n?n:par[n]=find(par[n]);
}
bool unite(int a,int b)
{
a=find(a),b=find(b);
if(a==b)return false;
par[b]=a;
return true;
}
int main(int argc, char** argv) {
int n;
scanf("%d",&n);
ini(n);
int number=0;
for(int i=1;i<=n;i++)
{
int temp;
scanf("%d",&temp);
edge[number]={0,i,temp};
number++;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
int temp;scanf("%d",&temp);
if(i==j)continue;
edge[number]={i,j,temp};
number++;
}
}
sort(edge,edge+number);
int wp=0,pickedge=0;
for(int i=0;i<number;i++)
{
if(unite(edge[i].s,edge[i].t))
{
wp+=edge[i].value;
pickedge++;
if(pickedge==n)
break;
}
}
printf("%d\n",wp);
return 0;
}