有向環最小權值覆蓋 MCMF KM

2021-09-28 15:37:47 字數 2839 閱讀 5413

題意:

給你乙個 n 個頂點 m 條邊的帶權有向圖, 要你把該圖分成 1 個或多個不相交的有向環. 且所有點都只被乙個有向環覆蓋.

問你該有向環所有權值的總和最小是多少?(保證有解)

思路:如果題目有重邊而且很多的話,可以先開二維陣列對重邊取min,最後再建圖

解法:將每個點拆成兩個點:

入點x和出點xx

如果存在邊a->b則建圖aa->b,權值為題目給的邊權

即a的出點連線b的入點,這樣圖就變成二分圖了.

出點作為左半部,入點為右半部

因為哈密頓環的定義是每個點只能走一次,則入度為1,出度為1,

拆點後每個點只能被用一次,而且出點只能連接入點(同半部無法連線),顯然二分圖

然後就可以用km求最小權或者mcmf解決

如果有點沒有被匹配到說明無解

km演算法即邊權取反然後求最大,如果有點沒有被匹配到說明無解

mcmf即源點連線左半部,匯點連線右半部建圖,如果最大流不等於點數n則無解

ps:最近inf習慣用1e9而不是0x3f3f3f3f

寫mcmf的時候忘記了,直接memset(inf),一度懷疑自己mcmf寫錯了

以後盡量用for

code(km):

#include

#include

#include

#include

#include

#include

using

namespace std;

const

int maxm=

205;

const

int inf=

1e9;

int g[maxm]

[maxm]

;int need[maxm]

;int lx[maxm]

,ly[maxm]

;int visx[maxm]

,visy[maxm]

;int now[maxm]

;int nx,ny;

int n,m;

bool

dfs(

int x)

}else}}

return0;

}voidkm(

)for

(int i=

1;i<=nx;i++)}

for(

int i=

1;i<=nx;i++

)while(1

)for

(int j=

1;j<=ny;j++)if

(dfs

(i))

break

;int d=inf;

for(

int j=

1;j<=ny;j++)}

for(

int j=

1;j<=nx;j++)}

for(

int j=

1;j<=ny;j++

)else}}

}}intmain()

}for

(int i=

1;i<=m;i++)km

();int ans=0;

int ok=1;

for(

int i=

1;i<=n;i++

)else}if

(ok)

else

}return0;

}

code(mcmf):
#include

#include

#include

#include

#include

#include

#include

using

namespace std;

const

int maxm=

305;

const

int inf=

2e8;

int g[maxm]

[maxm]

;int n,m;

struct nodee[maxm*maxm]

;int head[maxm]

,cnt;

int s,t;

int mincost,maxflow;

int mark[maxm]

;int d[maxm]

;int pre[maxm]

;void

init()

void

add(

int x,

int y,

int z,

int w)

bool

spfa()

d[s]=0

;while

(!q.

empty()

)}}}

return d[t]

!=inf;

}voidek(

)for

(int i=t;i!=s;i=e[pre[i]

].from)

maxflow+

=k; mincost+

=d[t]

*k;}

}signed

main()

}for

(int i=

1;i<=m;i++

) s=

0,t=n*2+

1;for(

int i=

1;i<=n;i++

)for

(int i=

1;i<=n;i++)}

}ek()

;if(maxflow==n)

else

}return0;

}

hdu 3488 Tour 有向帶權最小環覆蓋

題目鏈結 給定一張有向圖,每條邊有權值,求用1個或多個不相交的環覆蓋所有點並且環的權值和最小 檢視 include include include using namespace std typedef long long ll const int maxn 400 5 const int mod ...

最小環權值 floyd

find the mincost route time limit 2000msmemory limit 32768kb64bit io format i64d i64u submit status practice hdu 1599 description 杭州有n個景區,景區之間有一些雙向的路來...

ZOJ3166 找環值最小

題意 給你一幅圖,要你找乙個hotel能夠滿足出去回來,而且保證權值最小 思路 可以搜環,然後取最小權值環,拿個點 floyd方便,初始話自己到自己就是無窮,然後就列舉一下給出的hotel就好了 includeusing namespace std const int n 1e2 10 const ...