POJ 3189 Steady Cow Assignment
题意:每个奶牛对所有的牛棚有个排名(根据喜欢程度排的),每个牛棚能够入住的牛的数量有个上限,重新给牛分配牛棚,使牛棚在牛心中的排名差(所有牛中最大排名和最小排名之差)最小。
题目输入:
首先是两个数字N , B代表有N只牛B个牛棚
接下来的第一行B个数字代表每个牛棚最多能容纳多少牛。
接下来N行每行B个数字代表牛心中牛棚的排名。
我勒个去啊!真郁闷,WA了好多次终于AC发现自己错是因为重新构图后下标是从0开始的,改成下标从 1 开始的就AC了
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<vector> #include<queue> #include<cmath> using namespace std; #define INF 0x3fffffff #define maxn 1255 int n, m;///n 只牛 m个牛棚 bool vis[maxn]; int limt[maxn];///代表牛棚所能容纳的最大数量 vector<vector<int> > G; vector<vector<int> > P;///用来保存匹配的数据 bool Find(int u,int L,int R) { for(int i=L; i<=R; i++)///遍历u的前k条边 { int v = G[u][i-1]; if( !vis[v] ) { vis[v] = true; if(P[v].size() < limt[v]) { P[v].push_back(u); return true; } for(int j=0; j<P[v].size(); j++) { if( Find(P[v][j], L, R) ) { P[v].erase(P[v].begin()+j); P[v].push_back(u); return true; } } } } return false; } bool solve(int L,int R) { P.clear(); P.resize(m+10); for(int i=1; i<=n; i++) { memset(vis, false, sizeof(vis)); if( !Find(i, L, R) ) return false; } return true; } int main() { while(scanf("%d %d",&n, &m) != EOF) { G.clear(); G.resize(n+10); for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) { int a; scanf("%d", &a); G[i].push_back(a);///保存每只牛心中的排名 } } for(int i=1; i<=m; i++) scanf("%d", &limt[i]); int ans = INF; for(int i=1; i<=m; i++)///枚举一下。我们只允许选择前i个牛棚到j个牛棚 { for(int j=i; j<=m; j++) { if(j-i+1 > ans) break; if( solve(i, j) ) ans = j - i + 1; } } printf("%d\n", ans); } return 0; }