HDU 1045 Fire Net 2 분 도 Bipartite 문제 풀이
이 이분 도 는 헝가리 알고리즘 이 아니 라 그림 을 만 드 는 데 어려움 이 있다.높 은 추상 적 인 사고 가 필요 하 다.
건축 도:
1. 같은 줄 에 X 로 구분 되 지 않 는 칸 에 같은 번 호 를 표시 하고 X 로 분 리 된 다음 번 호 를 표시 합 니 다. 이렇게 하 는 것 은 점 을 줄 이기 위해 서 입 니 다. 모든 칸 을 레이 블 로 나 눌 필요 가 없고 더 작은 그림 을 만 드 는 데 편리 합 니 다.
2 같은 이치 로 같은 열의 칸 을 표시 한다.
3. 그 다음 에 같은 칸 의 줄 레이 블 과 열 레이 블 은 경로 가 있 고 다른 칸 에 없 는 것 은 모두 경로 가 없다 고 판단 합 니 다.
4. 이렇게 하면 줄 레이 블 과 열 레이 블 을 좌우 정점 으로 하여 2 분 도 를 구축 하 는 것 과 같다.
그리고 헝가리 알고리즘 을 사용 하여 2 분 그림 의 최대 매 칭 을 구 했 습 니 다.
정말 교묘 한 모델 링 이 야!
자신 이 직접 연구 하지 못 한 것 도 다른 사람의 코드 를 참고 한 후에 바로 두 드 렸 다.
사람 이 너 그 러 워 야 하 니 링크 를 주 는 것 이 좋 겠 다.http://www.cnblogs.com/kuangbin/archive/2011/08/09/2132830.html 그러나 그 는 순 코드 여서 모델 링 은 말 하지 않 았 다.
#include <stdio.h>
#include <vector>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <string>
#include <limits.h>
#include <stack>
#include <queue>
#include <set>
#include <map>
using namespace std;
int uN, vN;
int g[20][20];
int linker[20];
bool used[20];
char gra[5][5];
int graR[5][5];
int graL[5][5];
bool dfs(int u)
{
for (int v = 1; v <= vN; v++)
{
if (g[u][v] && !used[v])
{
used[v] = true;
if (-1 == linker[v] || dfs(linker[v]))
{
linker[v] = u;
return true;
}
}
}
return false;
}
int hungary()
{
int res = 0;
for (int i = 0; i < 20; i++)
{
linker[i] = -1;
}
for (int u = 1; u <= uN; u++)
{
memset(used, 0, sizeof(used));
if (dfs(u)) res++;
}
return res;
}
int main()
{
int n;
while (scanf("%d", &n) && n)
{
memset(graL, 0, sizeof(graL));
memset(graR, 0, sizeof(graR));
memset(g, 0, sizeof(g));
getchar();
for (int i = 0; i < n; i++)
{
gets(gra[i]);
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (gra[i-1][j-1] == 'X')
graL[i][j] = graR[i][j] = -1;
}
}
vN = uN = 0;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
while (graR[i][j] == -1 && j <= n) j++;
if (j > n) break;
uN++;
while (graR[i][j] != -1 && j <= n)
{
graR[i][j] = uN;
j++;
}
}
}
for (int j = 1; j <= n; j++)
{
for (int i = 1; i <= n; i++)
{
while (graL[i][j] == -1 && i <= n) i++;
if (i > n) break;
vN++;
while (graL[i][j] != -1 && i <= n)
{
graL[i][j] = vN;
i++;
}
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (graR[i][j] != -1) g[graR[i][j]][graL[i][j]] = 1;
}
}
printf("%d
", hungary());
}
return 0;
}
이 문 제 는 처음에 DFS 로 검색 해 봤 는데 데이터 가 이렇게 적 으 니 틀림없이 넘 길 수 있 을 것 이다.그러나 이 문제 의 검색 도 AC 를 한 번 에 하기 가 쉽 지 않 은 것 같 습 니 다. 저 는 처음부터 생각 을 잘 하지 못 했 습 니 다. 생각 을 잘못 사 용 했 습 니 다. WA 는 몇 번 이나 그림 을 그리 지 않 고 시 뮬 레이 션 을 하지 않 았 습 니 다. 실 수 를 할 확률 이 상당히 높 습 니 다.
const int MAX_N = 8;
char Maze[MAX_N][MAX_N];
int N;
bool isLegal(int r, int c)
{
if (Maze[r][c] != '.') return false;
bool legal = true;
for (int i = r-1; i >= 0 && legal; i--)
{
if (Maze[i][c] == 'X') break;
else if (Maze[i][c] != '.') legal = false;
}
for (int i = r+1; i < N && legal; i++)
{
if (Maze[i][c] == 'X') break;
else if (Maze[i][c] != '.') legal = false;
}
for (int j = c-1; j >= 0 && legal; j--)
{
if (Maze[r][j] == 'X') break;
else if (Maze[r][j] != '.') legal = false;
}
for (int j = c+1; j < N && legal; j++)
{
if (Maze[r][j] == 'X') break;
else if (Maze[r][j] != '.') legal = false;
}
return legal;
}
int ans;
void dfs(int one = 0)
{
bool flag = false;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
if (isLegal(i, j))
{
flag = true;
Maze[i][j] = '@';
dfs(one+1);
Maze[i][j] = '.';
}
}
}
if (flag)
{
ans = max(ans, one+1);//, cout<<one<<endl;;
}
}
int main()
{
while (~scanf("%d", &N) && N)
{
while (getchar() != '
') ;
for (int i = 0; i < N; i++)
{
gets(Maze[i]);
}
ans = 0;
dfs();
printf("%d
", ans);
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.