タイトル説明
農業のように、田舎に家でものをボーリング。1〜Nから番号n個のブロックがあり、農地。灌漑農業へ
我々はすべて知っているものは、魔術師であるとして、彼は空になるように黄河の水場に彼の魔法で、特定のMPを消費することができます。彼はまた、MPポータル一定量の水とティエンティエンの飲料水のこの作品を作り、2つの排水分野で確立消費することができます。(1 <= N <= 3E2)
天黄河の水の消費量をWiで、iは農地の数である(1 <=のWi <= 1E5)
確立された消費ポータルPijにある、I、Jは、農地の数である(1 <= Pijを<= 1E5、Pijを= PJI、PII = 0)
灌漑最小消費のすべてのフィールドのためのもの
説明を入力します。
1行目:n個
行に行2 N + 1:番号のWi
マトリックスマトリックス即ちPIJ:行2N + 1 N + 2行目
出力仕様
MPの最小消費値のもの
サンプル入力
4
5
4
4
3
0 2 2 2
2 0 3 3
2 3 0 4
2 3 4 0
サンプル出力
9
思考
各ファーム点を想像するであろう、2点間のMP重み付け縁の消費によって引き起こされるように、2つの点の間の水ファーム加重図となるように、考えることができます。次の質問は、この天国の水の消費量をどのように扱うかである私たちは、スーパー日間の起源として見られるだろう、それはまた、農地側の重み、すなわち転換MP消費量を指します。それが可能なすべての農地を灌漑し、少なくともを消費するようにするには、問題は、次の質問は、私たちが作成するグラフの最小全域木を見つける方法であるので、重み付きグラフの最小全域木を見つけることが問題に変換することができます。
クラスカルのアルゴリズムがあるが、それらは、2つのコレクションをマージセット、(互いに素なセットを使用してもよい)の同じ端部側には、すべてのエッジは、側面を調べるために昇順に重量、体重に従ってソートされ、ここでない場合に使用しました選択されたn個までの側縁部を選択し、(N + 1点で)、選択したエッジは、重みがMPの消費を最小限にするために合計されるグラフの最小スパニングツリーを形成することができます。
コード
#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;
}