BOJ) 11376. 열혈강호 2
문제:
강호네 회사에는 직원이 N명이 있고, 해야할 일이 M개가 있다. 직원은 1번부터 N번까지 번호가 매겨져 있고, 일은 1번부터 M번까지 번호가 매겨져 있다.
각 직원은 최대 두 개의 일을 할 수 있고, 각각의 일을 담당하는 사람은 1명이어야 한다.
각각의 직원이 할 수 있는 일의 목록이 주어졌을 때, M개의 일 중에서 최대 몇 개를 할 수 있는지 구하는 프로그램을 작성하시오.
해설:
전형적인 최대 유량 문제이다. 열혈 강호 1번이 간선의 capacity가 1이었다면,
src에서 직원에게 주는 간선의 capacity를 2로 증가시키고 flow를 흘려보내면 정답을 구할 수 있다.
#include <iostream> #include <algorithm> #include <string.h> #include <cstdio> using namespace std; int map[3005][3005]; int N, M; bool visited[3005]; int dfs(int p, int mn){ //cout<<p<<" "<<mn<<"\n"; if( p == M+N+1) return mn; visited[p] = 1; int pos = 0; for(int i=1; i<=M+N+1; i++){ if(!visited[i] && map[p][i] > 0){ mn = min(mn, map[p][i]); visited[i] = 1; pos = dfs(i, mn); if(pos) { map[p][i]-=pos; map[i][p]+=pos; break;} } } return pos; } int main(){ cin>>N>>M; for(int i=1; i<=N; i++){ map[0][i] = 2; int temp; scanf("%d",&temp); for(int j=0; j<temp; j++){ int x; scanf("%d",&x); map[i][x+N] = 1; } } for(int i=N+1; i<=M+N; i++) map[i][M+N+1]=1; while(1){ memset(visited,0,sizeof(visited)); int pos = dfs(0, 99999999); if(!pos) break; } int ans = 0; for(int i=N+1; i<=M+N; i++) ans += map[M+N+1][i]; cout<<ans; }
댓글
댓글 쓰기