https://kotlinlang.org/docs/multiplatform-mobile-create-first-app.html#create-the-project-from-a-template

 

Create your first cross-platform app | Kotlin

 

kotlinlang.org

위 링크의 내용을 따라가며 시작해 보기.

 

프로젝트 생성

프로젝트 생성시 프로젝트트리

 

Android Emulator

 

IOS 실기기가 없다면 다음과 같이 Configuration을 설정해 줍니다.

IOS Emulator

 

Common Main  수정해 보기

greet()는 iosMain, AndoridMain 프로젝트에서 불리는 공통 메서드이다.

package com.root.kmmstart

class Greeting {
    private val platform: Platform = getPlatform()

    fun greet(): String {
        return "Hello, ${platform.name}!"
    }
}

Platform Interface를 비니지스 로직에 필요한 동작을 정의하고 IOS, Android 각각 동작에 대해 구현한다.

package com.root.kmmstart

interface Platform {
    val name: String
}

expect fun getPlatform(): Platform
package com.root.kmmstart

import platform.UIKit.UIDevice

class IOSPlatform: Platform {
    override val name: String = UIDevice.currentDevice.systemName() + 
            " " + UIDevice.currentDevice.systemVersion
}

actual fun getPlatform(): Platform = IOSPlatform()
package com.root.kmmstart

class AndroidPlatform : Platform {
    override val name: String = "Android ${android.os.Build.VERSION.SDK_INT}"
}

actual fun getPlatform(): Platform = AndroidPlatform()

 

IOS, Android  UI 수정해 보기

UI Level은 각각 플랫폼에서 구현된다. (필자는 안드로이드 개발자라 SwiftUI에 대해서는 무지하다)

@Composable
fun GreetingView(text: String) {
    Column() {
        Text(text = text, color = Color.Red)
        Text(
            "this is Greeting View Composable Function in Android App!!!",
            modifier = Modifier.background(color = Color.Yellow)
        )
    }
}
struct ContentView: View {
   let greet = Greeting().greet()

   var body: some View {
      Text(greet)
      Text("this is Greeting View Swift UI in Ios App!!!")
   }
}

'Mobile > KMM(Kotlin MultiPlatform Mobile)' 카테고리의 다른 글

1. KMM 시작하기  (0) 2023.04.23

https://kotlinlang.org/docs/multiplatform-mobile-getting-started.html

 

Get started with Kotlin Multiplatform for mobile | Kotlin

 

kotlinlang.org

위 링크의 설명을 따라가며 시작해보기.

Set up an environment

개발을 위해 기본적으로 아래는 모두 설치해야 합니다.

Android Studio

작성일 기준 아래 정보로 진행했습니다.

Xcode

작성일 기준 아래 정보로 진행했습니다.

JDK

작성일 기준 아래 정보로 진행했습니다.

> java -version
openjdk version "17.0.6" 2023-01-17
OpenJDK Runtime Environment Temurin-17.0.6+10 (build 17.0.6+10)
OpenJDK 64-Bit Server VM Temurin-17.0.6+10 (build 17.0.6+10, mixed mode, sharing)

Kotlin Multiplatform Mobile plugin

Android Studio > Plugins 에서 설치 할 수 있습니다.

Kotlin plugin

프로젝트 생성 후 Android Studio 내에서 설정할 수 있습니다.

KDoctor

필수는 아니지만 원활한 진행을 위해 KDoctor도 설치해줍니다.

KDoctor works on macOS only.
> kdoctor
Environment diagnose (to see all details, use -v option):
[✓] Operation System
[✓] Java
[✓] Android Studio
[✓] Xcode
[✖] Cocoapods
  ✖ cocoapods not found
    Get cocoapods from https://guides.cocoapods.org/using/getting-started.html#installation

KDoctor 설치후 터미널에서 KDoctor로 체크하고 Cocoapods을 제외한 Tool들이 [v] 표시면 됩니다.

'Mobile > KMM(Kotlin MultiPlatform Mobile)' 카테고리의 다른 글

2. KMM 프로젝트 생성  (0) 2023.04.23

https://www.acmicpc.net/problem/2261

 

2261번: 가장 가까운 두 점

첫째 줄에 자연수 n(2 ≤ n ≤ 100,000)이 주어진다. 다음 n개의 줄에는 차례로 각 점의 x, y좌표가 주어진다. 각각의 좌표는 절댓값이 10,000을 넘지 않는 정수이다. 같은 점이 여러 번 주어질 수도 있다.

www.acmicpc.net


문제해설

이 문제는 "라인스위핑"알고리즘으로 풀어 보았습니다.

이문제의 정답률은 15% 미만이고, 인터넷상에 해답이나 설명이 없었다면 10%도 안나올거라고 생각됩니다.

 

입력 조건에서, 좌표의 갯수가 10만개 까지 들어오기 때문에

당연히 O(n^2) 풀이로는 TLE이 나올 것입니다.

적어도 O(NlgN)정도의 풀이가 필요 합니다.

 

우선 이문제의 핵심은, 답을 만들 수 있는 최소한의 후보들로만 비교하는 것입니다.

 편의를 위해, 초기에 기준을 잡고 기준을 기준으로

비교하면서 기준을 갱신해 나가며 답을 찾으면 됩니다.

( 주석으로 상세한 과정을 풀이했습니다 )

 

< 정렬 및 기준 잡기 >

	// x축 정렬을 하는 이유 ?
	// x축 정렬을 통해 x의축의 차이만으로 최대값 후보에서 여러 점들을 제외 시킬 수 있다.
	sort(vec.begin(), vec.end());
	// {y,x}으로 insert한 이유?
	// dx를 통해 if문으로 x축과의 거리는 처리 하였고,
	// map에 남아잇는 점들중에서 y축으로 lower_bound, upper_bound를 하기 위함이다.
	// = 0 인이 이유?
	// 어떤 값이든 크게 상관없지만 , INF보단 작고, -INF보단 커야한다.( lower_bound, upper_bound를 위해 )
	m[{vec[0].second, vec[0].first}] = 0; 
	m[{vec[1].second, vec[1].first}] = 0;
	ll ans = getDist(vec[0], vec[1]);

< 후보를 추가, 제외하면서 탐색 >

	int pos = 0;
	for (int i = 2; i < n; i++) {
		// pos부터 i-1번까지 i번째점과 비교를 한다.
		while (pos < i) {
			// x축간의 거리 차이
			int dx = vec[i].first - vec[pos].first;

			// pos( i 점 기준으로 현재 map 있는 가장 왼쪽 점 ) 과 i번째 점간의 x축 거리가
			// 더 작다면 pos점은 여전히 후보에 포함될 수 있다.
			if (dx * dx <= ans) break;
			
			// pos(i 점 기준으로 현재 map 있는 가장 왼쪽 점) 과 i번째 점간의 x축 거리가
			// 더 크다면 pos점은 더이상 더 작은 ans값을 만들어내지 못한다.( 후보에서 제외된다 )
			m.erase({ vec[pos].second,vec[pos].first });
			pos++;
		}

		// getDist 는 sqrt를 없이 반환했음으로...
		ll dis = sqrt(ans);

		// map에 남아있는 점들중에서
		// 현재 ans보다 작아 질 수 있는 후보 점들을 확인 하기위해 left, right를 찾고
		auto left = m.lower_bound({ vec[i].second - dis, -INF });
		auto right = m.upper_bound({ vec[i].second + dis, INF });

		// ans 갱신
		for (auto l = left; l != right; l++) {
			ans = min(ans, getDist( {l->first.second,l->first.first}, vec[i]));
		}

		// i번째점은 당연히 뒤에 확인할게 있음으로 후보 점이 된다.
		m[{vec[i].second, vec[i].first}] = 0;
	}

 

 

그림으로 보나, 코드로 보나 쉽게 이해가 가지 않을 수 있을 것 같습니다.

때문에 중간 중간 주석으로, 과정에대해서 나름 상세하게 설명해 보았습니다.

 


전체코드

#include <iostream>
#include <algorithm>
#include <cmath>
#include <map>
#include <vector>
#include <limits.h>
using namespace std;

#define INF INT_MAX
typedef long long ll;

// 문제에서 요구하는 거리는 거리의 제곱이기 때문에 sqrt를 사용하지 않았습니다.
ll getDist(pair<int,int> a, pair<int,int> b)
{
	int x1 = a.first;
	int y1 = a.second;
	int x2 = b.first;
	int y2 = b.second;
	return (x2-x1)*(ll)(x2 - x1) + (y2-y1)*(ll)(y2-y1);
}

vector<pair<int, int>> vec;
map<pair<int, int>, int> m;

int main()
{
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	int n; cin >> n;
	for (int i = 0; i < n; i++)
	{
		int x, y;
		cin >> x >> y;
		vec.push_back({ x,y });
	}
	// x축 정렬을 하는 이유 ?
	// x축 정렬을 통해 x의축의 차이만으로 최대값 후보에서 여러 점들을 제외 시킬 수 있다.
	sort(vec.begin(), vec.end());
	// {y,x}으로 insert한 이유?
	// dx를 통해 if문으로 x축과의 거리는 처리 하였고,
	// map에 남아잇는 점들중에서 y축으로 lower_bound, upper_bound를 하기 위함이다.
	// = 0 인이 이유?
	// 어떤 값이든 크게 상관없지만 , INF보단 작고, -INF보단 커야한다.( lower_bound, upper_bound를 위해 )
	m[{vec[0].second, vec[0].first}] = 0; 
	m[{vec[1].second, vec[1].first}] = 0;
	ll ans = getDist(vec[0], vec[1]);

	// pos = 0 부터, i = 2 부터인 이유?
	// 편의상 첫번째점과 두번째점을 (x축 정렬 기준 ) 을 기준으로 잡았다.
	// 밑의 코드의 for문을 돌리는대신 기준을 잡았다고 보면 된다.
	/*
	for(int i = 0 ; i < 2; i ++){
		...
	}
	*/
	int pos = 0;
	for (int i = 2; i < n; i++) {
		// pos부터 i-1번까지 i번째점과 비교를 한다.
		while (pos < i) {
			// x축간의 거리 차이
			int dx = vec[i].first - vec[pos].first;

			// pos( i 점 기준으로 현재 map 있는 가장 왼쪽 점 ) 과 i번째 점간의 x축 거리가
			// 더 작다면 pos점은 여전히 후보에 포함될 수 있다.
			if (dx * dx <= ans) break;
			
			// pos(i 점 기준으로 현재 map 있는 가장 왼쪽 점) 과 i번째 점간의 x축 거리가
			// 더 크다면 pos점은 더이상 더 작은 ans값을 만들어내지 못한다.( 후보에서 제외된다 )
			m.erase({ vec[pos].second,vec[pos].first });
			pos++;
		}

		// getDist 는 sqrt를 없이 반환했음으로...
		ll dis = sqrt(ans);

		// map에 남아있는 점들중에서
		// 현재 ans보다 작아 질 수 있는 후보 점들을 확인 하기위해 left, right를 찾고
		auto left = m.lower_bound({ vec[i].second - dis, -INF });
		auto right = m.upper_bound({ vec[i].second + dis, INF });

		// ans 갱신
		for (auto l = left; l != right; l++) {
			ans = min(ans, getDist( {l->first.second,l->first.first}, vec[i]));
		}

		// i번째점은 당연히 뒤에 확인할게 있음으로 후보 점이 된다.
		m[{vec[i].second, vec[i].first}] = 0;
	}

	cout << ans << "\n";
	
	return 0;
}

 


 

https://www.acmicpc.net/problem/1298

 

1298번: 노트북의 주인을 찾아서

어느 날 모든 학생들은 한 명이 한개의 노트북을 가지고 공부하던 도중, 자리를 바꾸다가 그만 노트북이 뒤섞이고 말았다. 대다수의 학생들은 자신의 노트북을 잘 알고 있어서 자신의 노트북을 받을 수 있었지만, 애석하게도 N명의 학생들이 정확히 자신의 노트북이 어떤것인지 알지 못했다. 왜냐하면 그들은 노트북을 구입한게 바로 어제였기 때문이다. 어차피 새것인 노트북, 바뀐들 어떠하랴. 그들에게 자신의 노트북이라고 생각되는 노트북들을 얘기해 보라고 했다. 이번에는

www.acmicpc.net


문제해설

각 시작 노드 ( 사람 ) 에서

노트북 주인이 없다면 flow를 발생시켜서

노트북을 갖게 하면 됩니다.


전체코드

#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define endl '\n'
//--------------------------------------------------------------------------------------

#define MAX_N 101

vector<int> map[MAX_N];
int occupy[MAX_N];
int occupied[MAX_N];
bool visit[MAX_N];
bool dfs(int x) {
	visit[x] = true;
	for (int i = 0; i < map[x].size(); i++) {
		int y = map[x][i];
		if (occupied[y] == -1 || (!visit[occupied[y]] && dfs(occupied[y]))) {
			occupy[x] = y;
			occupied[y] = x;
			return true;
		}
	}
	return false;
}

int main() {
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	int N, M; cin >> N >> M;
	for (int i = 0; i < M; i++) {
		int a, b; cin >> a >> b;
		map[a].push_back(b);
	}
	memset(occupy, -1, sizeof(occupy));
	memset(occupied, -1, sizeof(occupied));
	int ans = 0;
	for (int i = 1; i <= N; i++) {
		if (occupy[i] == -1) {
			memset(visit, false, sizeof(visit));
			if (dfs(i)) ans++;
		}
	}
	cout << ans << endl;
}

기타

'알고리즘 > [C++]BOJ' 카테고리의 다른 글

[백준BOJ] 2261 가장 가까운 두 점  (1) 2019.10.19
[백준BOJ] 11377 열혈강호 3  (0) 2019.10.14
[백준BOJ] 1671 상어의 저녁식사  (0) 2019.10.14

https://www.acmicpc.net/problem/11377

 

11377번: 열혈강호 3

첫째 줄에 직원의 수 N과 일의 개수 M, 일을 2개할 수 있는 직원의 수 K가 주어진다. (1 ≤ N, M ≤ 1,000, 1 ≤ K ≤ N) 둘째 줄부터 N개의 줄의 i번째 줄에는 i번 직원이 할 수 있는 일의 개수와 할 수 있는 일의 번호가 주어진다.

www.acmicpc.net


문제해설

열혈강호3  = 열혈강호1 + 열혈강호2

라고 보시면 되는 문제입니다. 

  • 우선 모든 사람에게 한가지 일을 시킵니다.
  • 한가지 일을 한 사람들 중에서 한가지일을 더 시킵니다. 

전체코드

#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
using namespace std;
typedef long long ll;\
typedef pair<int, int> pii;
#define endl '\n'
#define cout1(a) {cout << a << endl;}
#define cout2(a,b) {cout << a << " " < b << endl;}
//--------------------------------------------------------------------------------------

#define MAX_N 1001
vector<int> map[MAX_N];
int work[MAX_N];
int worked[MAX_N];
bool visit[MAX_N];
int workCnt[MAX_N];
bool dfs(int x) {
	visit[x] = true;
	for (int i = 0; i < map[x].size(); i++) {
		int y = map[x][i];
		if (worked[y] == -1 || (visit[worked[y]] == false && dfs(worked[y]))) {
			work[x] = y;
			worked[y] = x;
			return true;
		}
	}
	return false;
}



int main() {
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	int N, M, K; cin >> N >> M >> K;
	for (int i = 1; i <= N; i++) {
		int C; cin >> C;
		for (int j = 0; j < C; j++) {
			int data; cin >> data;
			map[i].push_back(data);
		}
	}
	memset(work, -1, sizeof(work));
	memset(worked, -1, sizeof(worked));
	int ans = 0;
	int k = 0;
	for (int i = 1; i <= N; i++) {
		if (work[i] == -1) {
			memset(visit, false, sizeof(visit));
			if (dfs(i)) {
				workCnt[i]++;
				ans++;
			}
		}
	}

	for (int i = 1; i <= N; i++) {
		if (workCnt[i] == 1) {
			memset(visit, false, sizeof(visit));
			if (k < K && dfs(i)) {
				ans++;
				k++;
			}
		}
	}

	cout << ans << endl;
}

기타

https://www.acmicpc.net/problem/1671

 

1671번: 상어의 저녁식사

어떤 상어는 저녁식사로 서로를 먹는다. 모든 상어는 자신과 다른 상어의 크기, 속도, 지능을 수치로 나타낸 것을 알고 있다. 만약, 상어 A의 크기, 속도, 지능이 상어 B의 크기, 속도, 지능보다 크거나 같다면 상어 A는 상어 B를 먹을 수 있다. 그러나, 상어들의 왕 김재홍은 상어들이 많이 없어지는 것을 방지하기 위해서 한 상어가 최대 두 개의 상어만 먹을 수 있게 했다. 상어들은 김재홍의 말을 모두 듣는다. N마리 상어의 크기, 속도, 지능이 주어졌

www.acmicpc.net


문제해설

밑의 문제와 비슷한 유형의 문제입니다. 

단, 문제 조건을 잘 읽고 따져야 되는 문제입니다.

 

2019/10/13 - [알고리즘/BOJ] - [백준BOJ] 11376 열혈강호2

 

[백준BOJ] 11376 열혈강호2

https://www.acmicpc.net/problem/11376 11376번: 열혈강호 2 강호네 회사에는 직원이 N명이 있고, 해야할 일이 M개가 있다. 직원은 1번부터 N번까지 번호가 매겨져 있고, 일은 1번부터 M번까지 번호가 매겨져 있..

polohee81.tistory.com

 

우선 문제에서 제시한 조건에 의해서 내림차순으로 정렬을 해줍니다.

정렬된 vector 에서 i < j 라고 할떄

  • vec[i] 는 vec[j] 를 잡아먹을 수 있고( 단 , 속도, 지능, 크기가 모두 크거나 같야아 합니다 )
  • vec[j] 는 vec[i] 를 어떠한 경우에도 잡아 먹을 수 없습니다.

조건에 만족하는 경우 i 에서 j 에서 가능 경로가 있다고 생각하고 ( 간선의 가중치 1 )

한 상어당 2번의 flow를 발생시키면 됩니다.

 

 


전체코드

#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define endl '\n'
//--------------------------------------------------------------------------------------

#define MAX_N 51
class Shark {
public:
	int size, speed, intel;
	Shark(int size, int speed, int intel) {
		this->size = size; this->speed = speed; this->intel = intel;
	}
	bool operator < (const Shark  & b) const {
		if (this->size == b.size && this->speed == b.speed) {
			return this->intel > b.intel;
		}if (this->size == b.size) {
			return this->speed > b.speed;
		}
		else {
			return this->size > b.size;
		}
	}

	bool operator >= (const Shark  & b) const {
		if (this->size >= b.size && this->speed >= b.speed && this->intel >= b.intel) {
			return true;
		}
		else {
			return false;
		}
	}
}; vector<Shark> shark;

int eat[MAX_N];
int eated[MAX_N];
bool visit[MAX_N];
int N;

bool fun(int n) {
	visit[n] = true;
	for (int i = n + 1; i < N; i++) {
		if (shark[n] >= shark[i]) {
			if (eated[i] == -1 || (!visit[eated[i]] && fun(eated[i]))) {
				eat[n] = i;
				eated[i] = n;
				return true;
			}
		}
	}
	return false;
}


int main() {
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	cin >> N;
	for (int i = 0; i < N; i++) {
		int a, b, c; cin >> a >> b >> c;
		shark.push_back(Shark(a, b, c));
	}
	sort(shark.begin(), shark.end());
	//cout << "정렬 후" << endl;
	//for (const auto &x : shark)
	//	cout << x.size << "  " << x.speed << " " << x.intel << endl;
	int ans = N;
	memset(eat, -1, sizeof(eat));
	memset(eated, -1, sizeof(eated));

	for (int i = 0; i < N; i++) {
		if (eat[i] == -1) {
			memset(visit, false, sizeof(visit));
			if (fun(i)) ans--;
			if (fun(i)) ans--;
		}
	}
	cout << ans << endl;
}

기타

'알고리즘 > [C++]BOJ' 카테고리의 다른 글

[백준BOJ] 11377 열혈강호 3  (0) 2019.10.14
[백준BOJ] 6086 최대 유량  (0) 2019.10.13
[백준BOJ] 11376 열혈강호2  (0) 2019.10.13

https://www.acmicpc.net/problem/6086

 

6086번: 최대 유량

문제 농사꾼 존은 소들이 충분한 물을 마시길 원했다. 그래서 농장에서 우물에서 외양간을 잇는 N개의 배수관의 지도를 만들기로 했다. 존은 아주 다양한 크기의 배수관들이 완전히 우연한 방법으로 연결돼있음을 알았다. 존은 파이프를 통과하는 유량을 계산하고 싶다. 두개의 배수관이 한줄로 연결 돼 있을 때 두 관의 유량 중 최솟값으로 흐르게 된다. 예를 들어 용량이 5인 파이프가 용량이 3인 파이프와 연결되면 한개의 용량 3짜리 파이프가 된다. +---5---+

www.acmicpc.net

 


문제해설

"에드몬드 카프 알고리즘(Edmonds-Karp algorithm)" 을 활용한 "네트워크 플로우" 문제입니다.

문제 제목부터가 "최대 유량"이기 때문에, 유량관련 알고리즘을 사용해야 합니다.

에드몬드 카프 알고리즘을 모르시는분은 밑의 동영상을 참고하시면 좋을 것 같습니다.

 

https://youtu.be/Wn51_ypG_T8

위, 유튜브에서 올라온 코드 그대로 작성하면 AC를 맞을 수 있습니다.

단, 조심해야 할 것은

입력 부분에서 

		map[A].push_back(B);
		map[B].push_back(A);
		c[A][B] += w;
		c[B][A] += w;

위와 같이, 양방향에 대해서 처리를 해줘야 됩니다.

주석을 통해서 자세한 풀이를 확인해주세요.


전체코드

#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <limits.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define endl '\n'
//--------------------------------------------------------------------------------------
#define MAX_N 52

int c[MAX_N][MAX_N]; // 흐르는 양
int f[MAX_N][MAX_N]; // 흐르고 있는 양
int visit[MAX_N]; // 한번 que가 돌때마다 visit 이 -1로 초기화 된다.
vector<int> map[MAX_N];

// 애드몬드 카프 알고리즘
int maxFlow(int start, int end) {
	int ret = 0;
	while (1) {
		memset(visit, -1, sizeof(visit)); // 모든 정점 방문 초기화
		queue<int> q;
		q.push(start); // start 점에서 end 점까지 흘려 보낸다.
		while (!q.empty()) { 
			int front = q.front(); q.pop();
			for (int i = 0; i < map[front].size(); i++) {
				int e = map[front][i];
				if (c[front][e] - f[front][e] > 0 && visit[e] == -1) {
					// 흐를 수 있다 && 이번 BFS에서 흐른적이 없다.
					q.push(e); 
					visit[e] = front; // front에서 e로 흘렀다는 것을 알려준다.
					if (e == end) break; // end 점을 찾게되면 flow 중지
				}
			}
		}
		// 모든 경로를 찾은 경우
		if (visit[end] == -1) break; // BFS에서 end 점을 방문하지 않았다 -> 더이상 흐르는 경우가 없다.
		int flow = INT_MAX; // 최솟값을 찾기 위함
		for (int i = end; i != start; i = visit[i]) {
			flow = min(flow, c[visit[i]][i] - f[visit[i]][i]);
		}

		for (int i = end; i != start; i = visit[i]) {
			// 음의 간선이 있다고 생각함으로써 모든 경우의 수를 탐색 할 수 있게 된다.
			f[visit[i]][i] += flow;
			f[i][visit[i]] -= flow;
		}
		ret += flow;
	}
	return ret;
}

int getID(char c) {
	int ret;
	if (c >= 97) {
		ret = c - 97;
		ret += 26;
	}
	else {
		ret = c - 65;
	}
	return ret;
}

int main() {
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	int N; cin >> N;
	for (int i = 0; i < N; i++) {
		char a, b; int w; cin >> a >> b >> w;
		int A = getID(a);
		int B = getID(b);
		//cout << a << " : " << A << " " << b << " : "<< B << endl;
		map[A].push_back(B);
		map[B].push_back(A);
		c[A][B] += w;
		c[B][A] += w;
	}
	cout << maxFlow(0, 25) << "\n";
}

기타

'알고리즘 > [C++]BOJ' 카테고리의 다른 글

[백준BOJ] 1671 상어의 저녁식사  (0) 2019.10.14
[백준BOJ] 11376 열혈강호2  (0) 2019.10.13
[백준BOJ] 11375 열혈강호  (0) 2019.10.13

https://www.acmicpc.net/problem/11376

 

11376번: 열혈강호 2

강호네 회사에는 직원이 N명이 있고, 해야할 일이 M개가 있다. 직원은 1번부터 N번까지 번호가 매겨져 있고, 일은 1번부터 M번까지 번호가 매겨져 있다. 각 직원은 최대 두 개의 일을 할 수 있고, 각각의 일을 담당하는 사람은 1명이어야 한다. 각각의 직원이 할 수 있는 일의 목록이 주어졌을 때, M개의 일 중에서 최대 몇 개를 할 수 있는지 구하는 프로그램을 작성하시오.

www.acmicpc.net


문제해설

열혈강호 1 에서 바뀐 조건은 한사람이 2가지의 일을 할 수 있다는 것이다.

visit을 초기화 하고나서,

2번의 flow를 발생시키면 된다.


전체코드

#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define endl '\n'
//--------------------------------------------------------------------------------------

#define MAX_N 1001
vector<int> map[MAX_N];

int employee[MAX_N];
int work[MAX_N];
bool visit[MAX_N];

bool fun(int s) {
	visit[s] = true;
	for (int i = 0; i < map[s].size(); i++) {
		if (work[map[s][i]] == -1 || (!visit[work[map[s][i]]] && fun(work[map[s][i]]))) {
			employee[s] = map[s][i];
			work[map[s][i]] = s;
			return true;
		}
	}
	return false;
}

int main() {
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	int N, M; cin >> N >> M;

	for (int i = 1; i <= N; i++) {
		int s; cin >> s;
		for (int j = 0; j < s; j++) {
			int data; cin >> data;
			map[i].push_back(data);
		}
	}
	memset(employee, -1, sizeof(employee));
	memset(work, -1, sizeof(work));
	int ans = 0;
	for (int i = 1; i <= N; i++) {
		if (employee[i] == -1) {
			memset(visit, false, sizeof(visit));
			if (fun(i)) ans++;
			if (fun(i)) ans++;
		}
	}
	cout << ans << endl;
}

 


기타

 

'알고리즘 > [C++]BOJ' 카테고리의 다른 글

[백준BOJ] 6086 최대 유량  (0) 2019.10.13
[백준BOJ] 11375 열혈강호  (0) 2019.10.13
[백준BOJ] 2188 축사 배정  (0) 2019.10.13

+ Recent posts