최소 트 리 이분 도 템 플 릿 생 성
Prim 소박 판 O (n ^ 2)
for i 0 ~ n
우선 외부 거리 에서 가장 가 까 운 점 할당 t 를 집합 합 니 다.
t 로 다른 점 에서 집합 까지 의 거 리 를 업데이트 합 니 다.
st[t] = true;
* 그 중에서 점 에서 집합 까지 의 거 리 는 집합 외 점, 집합 내 점 까지 의 거리, 가장 작은 쪽 으로 정의 합 니 다.
#include
#include
#include
using namespace std;
const int N = 510,INF = 0x3f3f3f3f;
int g[N][N],dist[N],n,m;
bool st[N];
int prim(){
int ret = 0;
memset(dist,0x3f,sizeof dist);
for(int i = 0;i < n; ++i){
int t = -1;
for(int j = 1;j <= n; ++j){ // ,
if(!st[j] && (t == -1 || dist[j] < dist[t]))
t = j;
}
st[t] = 1;
if(i && dist[t] == INF) return -1; // INF, ,
//
if(i) ret += dist[t];// , ,dist t
// , ,( , 1-1 , -10)
for(int j = 1;j <= n; ++j) dist[j] = min(dist[j],g[t][j]); // t
// for , t ,j
}
return ret;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int u,v,w;
cin >> n >> m;
for(int i = 0;i <= n; ++i)
for(int j = 0;j <= n; ++j)
g[i][j] = g[j][i] = INF;
while(m--){
cin >> u >> v >> w;
g[u][v] = g[v][u] = min(g[u][v],w);
}
int ans = prim();
cout << ans ;
return 0;
}
Kruskal O(mlogm)
#include
#include
#include
using namespace std;
const int M = 2e5 + 10,N = 1e5 + 10;
int p[N],n,m;
struct Edge{
int a,b,w;
bool operator < (const Edge & W) const{
return w < W.w;
}
}edges[M];
int find(int x){
if(x != p[x]) p[x] = find(p[x]);
return p[x];
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int cnt = 0,ret = 0;
cin >> n >> m;
for(int i = 0;i < m; ++i){
cin >> edges[i].a >> edges[i].b >> edges[i].w;
}
sort(edges,edges + m);
for(int i = 1;i <= n; ++i) p[i] = i;
for(int i = 0;i < m; ++i){
int a = edges[i].a,b = edges[i].b,w = edges[i].w;
a = find(a),b = find(b);
if(a != b){
p[a] = b;
ret += w;
cnt ++;
}
}
if(cnt < n-1) cout << "impossible";
else cout << ret ;
return 0;
}
이분 도
염색법 (DFS 로 이분 도 판정) O (m + n)
성질:
알고리즘 흐름:
#include
#include
using namespace std;
const int N = 1e5 + 10;
int e[N],ne[N],w[N],h[N],idx,n,m;
int color[N];
void add(int a,int b,int c){
e[idx] = b;
w[idx] = c;
ne[idx] = h[a];
h[a] = idx ++;
}
bool dfs(int u,int c){
color[u] = c;
for(int i = h[u];i != -1;i = ne[i]){
int j = e[i];
if(!color[j]){
if(!dfs(j,3-c)) return 0;
}
else if(color[j] == c) return 0;
}
return 1;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
memset(h,-1,sizeof h);
int a,b,c;
cin >> n >> m;
for(int i = 0;i < m; ++i){
cin >> a >> b >> c;
add(a,b,c);
add(b,a,c);
}
bool f = 1;
for(int i = 1;i <= n; ++i){
if(!color[i] && !dfs(i,1)){
f = 0;
break;
}
}
if(f) cout << "Yes";
else cout <
헝가리 알고리즘 (최대 일치 요구) O (m + n) 의 실제 운행 시간 은 O (mn) 보다 훨씬 적다.
알고리즘 흐름:
#include
#include
using namespace std;
const int N = 510,M = 1e5 + 10;
int n1,n2,m;
int h[N],e[M],ne[M],idx,match[N];
bool st[N];
void add(int a,int b){
e[idx] = b;
ne[idx] = h[a];
h[a] = idx ++;
}
bool find(int x){
for(int i = h[x];i != -1;i = ne[i]){
int j = e[i];
if(!st[j]){
st[j] = 1;
if(match[j] == 0 || find(match[j])){
match[j] = x;
return 1;
}
}
}
return 0;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int u,v,res = 0;
cin >> n1 >> n2 >> m;
memset(h,-1,sizeof h);
while(m--){
cin >> u >> v;
add(u,v);
}
for(int i = 1;i <= n1; ++i){
memset(st,0,sizeof st);
if(find(i)) res ++;
}
cout << res;
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.