Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 6023 | Accepted: 2078 |
Description
Input
Output
Sample Input
6 4 1 2 3 4 2 3 1 4 4 2 3 1 3 1 2 4 1 3 4 2 1 4 2 3 2 1 3 2
Sample Output
2
题意:
有n头牛,m个牛棚,每个牛棚都有一定的容量(就是最多能装多少只牛),然后每只牛对每个牛圈的喜好度不同(就是所有牛圈在每个牛心中都有一个排名),然后要求所有的牛都进猪圈,牛棚在牛心中的排名差计算方法为:所有牛中最大排名和最小排名之差。问最小的排名差。
英语不好太坑了 ,理解错了题意,以测试数据举例:
1 2 3 4
2 3 1 4
4 2 3 1
3 1 2 4
1 3 4 2
1 4 2 3
2 1 3 2
前6行是每头牛对牛棚的排名, 第二行2 3 1 4 代表的是 对第二头牛而言,第二个牛棚排第一,第三个牛棚排第二,第一个牛棚排第三,第四个牛棚排第四。
不是第一个牛棚排第二,第二个牛棚排第三,第三个牛棚排第一,第四个牛棚排第四。这点理解搓个 ,wa了好多遍,英语不好真是要哭了。
解析:这一题其实不难,数据比较小,可以用最大流来写,建图有点麻烦,下面是建图过程:
(1)首先虚拟一个源点,汇点。
(2)源点向每头牛建边, 权值为1,
(3)牛棚向汇点建边,权值为每个牛棚的容量。
(4)枚举牛棚的最差排名和最好排名(即枚举排名差) ,在这个排名之内牛和这个牛棚建边。
看看每种情况判断是否合法(是否满流),取最小值。
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #define maxn 1200 #define maxm 100005 #define INF 0x3f3f3f3f using namespace std; int n, m; struct node { int u, v, cap, flow, next; }; node edge[maxm]; int head[maxn], cnt; int cur[maxn]; int dist[maxn], vis[maxn]; int num[maxn];//每个牛棚的容量 int val[1200][25]; void init(){ cnt = 0; memset(head, -1, sizeof(head)); } void add(int u, int v, int w){ node E; edge[cnt] = {u, v, w, 0, head[u]}; head[u] = cnt++; edge[cnt] = {v, u, 0, 0 ,head[v]}; head[v] = cnt++; } void input(){ for(int i = 1; i <= n; ++i) for(int j = 1; j <= m; ++j) scanf("%d", &val[i][j]); for(int i = 1; i <= m; ++i){ scanf("%d", &num[i]); } } void getmap(int l, int r){ for(int i = 1; i <= n; ++i) add(0, i, 1); for(int j = 1; j <= m; ++j) add(n + j, n + m + 1, num[j]); // for(int i = 1; i <= n; ++i) // for(int j = 1; j <= m; ++j) // if(val[i][j] >= l && val[i][j] <= r) // add(i, j + n, 1); for(int i = 1; i <= n; ++i) for(int j = l; j <= r; ++j) add(i, val[i][j] + n, 1); } bool BFS(int st ,int ed){ queue<int>q; memset(vis, 0 ,sizeof(vis)); memset(dist, -1, sizeof(dist)); vis[st] = 1; dist[st] = 0; q.push(st); while(!q.empty()){ int u = q.front(); q.pop(); for(int i = head[u]; i != -1; i = edge[i].next){ node E = edge[i]; if(!vis[E.v] && E.cap > E.flow){ vis[E.v] = 1; dist[E.v] = dist[u] + 1; if(E.v == ed) return true; q.push(E.v); } } } return false; } int DFS(int x, int ed, int a){ if(x == ed || a == 0) return a; int flow = 0, f; for(int &i = cur[x]; i != -1; i = edge[i].next){ node &E = edge[i]; if(dist[E.v] == dist[x] + 1 && (f = DFS(E.v, ed, min(a, E.cap - E.flow))) > 0){ E.flow += f; edge[i ^ 1].flow -= f; a -= f; flow += f; if(a == 0) break; } } return flow; } int maxflow(int st, int ed){ int flowsum = 0; while(BFS(st,ed)){ memcpy(cur, head, sizeof(head)); flowsum += DFS(st, ed, INF); } return flowsum; } int main(){ while(scanf("%d%d", &n, &m) != EOF){ input(); int ans = INF; for(int i = 1; i <= m; ++i){//枚举排名的下界 for(int j = i; j <= m; ++j){//枚举排名的上界 init(); getmap(i, j); if(maxflow(0, n + m + 1) == n) ans = min(ans, j - i + 1); } } printf("%d\n", ans); } return 0; }