sgu 218 分类: sgu 2015-06-21 17:04 22人阅读 评论(0) 收藏
二分答案+二分图匹配
时间复杂度:
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<cstring>
#include<map>
#include<string>
#include<stack>
#include<queue>
#include<utility>
#include<iostream>
#include<algorithm>
const int maxn = 505, INF = 0x3f3f3f3f;
int n, w[maxn][maxn];
bool hash[maxn];
int ans, link[maxn];
bool find(int x, int k)
{
for(int y = 1; y <= n; y++)
if(!hash[y] && w[x][y] <= k)
{
hash[y] = true;
if(!link[y] || find(link[y],k))
{
link[y] = x;
return true;
}
}
return false;
}
bool check(int key)
{
memset(link, 0, sizeof(link));
for(int i = 1; i <= n; i++)
{
memset(hash, false, sizeof(hash));
if(!find(i, key)) return false;
}
return true;
}
void MainWork(int l,int r)
{
while(l + 1 != r)
{
int mid = (l + r)>>1;
if(check(mid))
r = mid;
else
l = mid;
}
ans = r;
}
int main()
{
int wmax = -INF, wmin = INF;
#ifndef ONLINE_JUDGE
freopen("sgu218.in","r",stdin);
freopen("sgu218.out","w",stdout);
#endif
std::cin >> n;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
{
std::cin >> w[i][j];
wmax = std::max(wmax, w[i][j]);
wmin = std::min(wmin, w[i][j]);
}
MainWork(wmin - 1, wmax + 1);
std::cout << ans << std::endl, check(ans);
for(int i = 1; i <= n; i++)
std::cout << link[i] << ' ' << i << std::endl;
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。