ZOJ 2342 KM演算法 不等式

2021-06-26 02:48:04 字數 1385 閱讀 9653

題意:給你n個點,m條邊,前n-1條邊可以構成乙個生成樹,每條邊都有乙個權值,現在讓你調整權值,使得前n-1條邊構成這幅圖的最小生成樹,所有|ci-di|的和最小。

分析:首先我們可以發現,前n-1條邊要構成最小生成樹,那麼這些邊的權值只能減小,後n~m的邊只能增大,我們先將前n-1條邊構成一棵生成樹,然後對於後面的n~m的邊,假設任意這些邊中的一條為j,則加入這條邊就會產生環,為了一開始這條j邊不能加入生成樹,則這個環裡面的任意一條邊的權值要<=j。假設改變後的權值表示為ci-li,cj+lj,則有ci-li<=cj+lj,即為li+lj>=ci-cj,設ci-cj為wij,則為li+lj>=wij,到了這裡有沒有感覺就是km匹配應該滿足的頂標條件呢?其實我們要的是它滿足條件的最小權值,轉化為km的最大權值匹配,最後頂標陣列就是一組解。

**:#pragma comment(linker,"/stack:102400000,102400000")

#include #include #include #include #include #include #include #include #include #include #include using namespace std;

typedef long long ll;

const int maxn=505;

const int maxm=1000005;

const int inf=1000000000;

struct edgenodeedge[maxm];

int head[maxn],cnt,cost[maxn],vis[maxn];

void add(int x,int y,int id)

void init()

int n,nx,ny,m;

int march[maxn],lx[maxn],ly[maxn],slack[maxn];

int visx[maxn],visy[maxn],w[maxn][maxn];

int dfs(int x)

}else if(slack[y]>t)

slack[y]=t;

}return 0;

}int km()

}int res=0;

for(i=1;i<=ny;i++)

if(march[i]>-1)

res+=w[march[i]][i];

return res;

}bool find(int x,int y,int id)

}return 0;

}int main()

{ int x,y,z,id,i,t;

scanf("%d",&t);

while(t--)

{scanf("%d%d",&n,&m);

init();

for(i=1;i

演算法題 不等式數列

度度熊最近對全排列特別感興趣,對於1到n的乙個排列,度度熊發現可以在中間根據大小關係插入合適的大於和小於符號 即 和 使其成為乙個合法的不等式數列。但是現在度度熊手中只有k個小於符號即 和n k 1個大於符號 即 度度熊想知道對於1至n任意的排列中有多少個排列可以使用這些符號使其為合法的不等式數列。...

關於MATLAB遺傳演算法工具箱不等式約束

過去很久了,之前寫 的經驗分享一下。寫畢業 的時候需要用到遺傳演算法,網上查了很多資料,由於沒時間認真去學演算法的內部結構,最後還是選擇了matlab自帶的遺傳演算法工具箱 matlab2017 ga 看著前輩們寫的教程很快熟悉了那個操作介面,功能很強大,我先嘗試輸了簡單的函式,很快就把準確的結果求...

運用三角不等式加速Kmeans聚類演算法

引言 最近在刷 資料探勘導論 第九章,9.5.1小節有提到,可以用三角不等式,減少不必要的距離計算,從而達到加速聚類演算法的目的。這在超大資料量的情況下,尤為重要。但是書中並沒有給出解釋和證明。本文以k means聚類演算法為代表,講解下怎麼利用三角不等式減少計算過程。任一三角形,兩邊之和大於第三邊...