UVALive 4957 Fake scoreboard
题意就是有n个队伍和m个题目
给出了每个队伍解决的题目数量
每个题目也给出了被解决的次数
然后求一个方阵。
N,Y表示每个队伍是否过了哪个题目。
要求字典序最小。
这题给人的第一反应就是网络流。
虽然用网络流并不是最优算法。
但绝对是最直观的。
行和列分成两部分点。
源点向行连边。
行向列连边
列向终点连边
就行了
然后字典序要求最小。
那么就要枚举删边了。
我们先跑一遍网络流
然后从方阵左上角开始枚举。
每到一个枚举的位置,如果这个位置在第一次跑的网络流中就没有流量的话。显然这个位置可以放N
如果这个位置跑流量了,就要试着删边找增广了
将此边删除。 然后建两个新的源和汇。
源向行标号连一个1容量的边
列标号向新的汇连一个1容量的边
然后我们求新源汇的最大流
如若流量大于0,说明找到增光,此边可删,就删掉边,这个位置放N
否则这位置就Y。 不过同样把边删掉,以防以后找增广找到这。
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <queue>
#include <vector>
#define eps 1e-8
#define MAXN 366
#define MAXM 51111
#define INF 111111111
using namespace std ;
int nt, m;
int t[MAXN], p[MAXN];
struct Edge
{
int v, next;
int w;
}edge[MAXM];
int head[MAXN], e;
int id[MAXN][MAXN];
void init()
{
memset(head, -1, sizeof(head));
e = 0;
}
inline void add(int u, int v, int w)
{
edge[e].v = v;
edge[e].w = w;
edge[e].next = head[u];
head[u] = e++;
edge[e].v = u;
edge[e].w = 0;
edge[e].next = head[v];
head[v] = e++;
}
int h[MAXN], gap[MAXN];
int src, des, n;
int dfs(int pos, int cost)
{
if(pos == des) return cost;
int j, minh = n - 1;
int lv = cost, d;
for(j = head[pos]; j != -1; j = edge[j].next)
{
int v = edge[j].v;
int w = edge[j].w;
if(w > 0)
{
if(h[v] + 1 == h[pos])
{
if(lv < edge[j].w) d = lv;
else d = edge[j].w;
d = dfs(v, d);
edge[j].w -= d;
edge[j ^ 1].w += d;
lv -= d;
if(h[src] >= n) return cost - lv;
if(lv == 0) break;
}
if(h[v] < minh) minh = h[v];
}
}
if(lv == cost)
{
--gap[h[pos]];
if(gap[h[pos]] == 0) h[src] = n;
h[pos] = minh + 1;
++gap[h[pos]];
}
return cost - lv;
}
int sap()
{
int ret = 0;
memset(gap, 0, sizeof(gap));
memset(h, 0, sizeof(h));
//gap[0] = n;
while(h[src] < n) ret += dfs(src, INF);
return ret;
}
char out[MAXN][MAXN];
int S, T;
bool ok(int t1, int t2)
{
int k = id[t1][t2];
if(edge[k].w == 1)
{
edge[k].w = 0;
return true;
}
edge[k ^ 1].w = 0;
src = S;
des = T;
int e1 = e;
add(S, t1, 1);
int e2 = e;
add(t2 + nt, T, 1);
if(sap()){
edge[e1 ^ 1].w = edge[e2 ^ 1].w = 0;
return true;
}
edge[e1].w = edge[e2].w = 0;
return false;
}
int main()
{
//freopen("C:/D.in", "r", stdin);
//freopen("C:/DD.out", "w", stdout);
int cas = 0;
while(scanf("%d%d", &nt, &m) != EOF)
{
if(nt == 0 && m == 0) break;
if(cas) puts("");
cas++;
int sum1 = 0, sum2 = 0;
init();
for(int i = 1; i <= nt; i++)
{
scanf("%d", &t[i]);
sum1 += t[i];
}
for(int j = 1; j <= m; j++)
{
scanf("%d", &p[j]);
sum2 += p[j];
}
if(sum1 != sum2)
{
puts("Impossible");
continue;
}
src = nt + m + 1;
des = nt + m + 2;
S = nt + m + 3;
T = nt + m + 4;
n = T;
for(int i = 1; i <= nt; i++)
for(int j = 1; j <= m; j++)
{
id[i][j] = e;
add(i, j + nt, 1);
}
for(int i = 1; i <= nt; i++)
add(src, i, t[i]);
for(int i = 1; i <= m; i++)
add(i + nt, des, p[i]);
int ans = sap();
if(ans != sum1)
{
puts("Impossible");
continue;
} for(int i = 1; i <= nt; i++)
for(int j = 1; j <= m; j++)
{
if(ok(i, j)) putchar('N');
else putchar('Y');
if(j == m) printf("\n");
}
}
return 0;
}
UVALive 4957 Fake scoreboard的更多相关文章
- UVALive - 4108 SKYLINE[线段树]
UVALive - 4108 SKYLINE Time Limit: 3000MS 64bit IO Format: %lld & %llu Submit Status uDebug ...
- UVALive - 3942 Remember the Word[树状数组]
UVALive - 3942 Remember the Word A potentiometer, or potmeter for short, is an electronic device wit ...
- UVALive - 3942 Remember the Word[Trie DP]
UVALive - 3942 Remember the Word Neal is very curious about combinatorial problems, and now here com ...
- Fake chat script for website download
Are you searching for free fake webchat script then you are at the right place go get download your ...
- fake gucci outlet perform a couple associated with things in great trust
Based on my a lot of years of encounter within Taobao, purchase bags must go to the high reputation ...
- Zyxel Switch-How to block a fake DHCP server without enabling DHCP snooping?
How to block a fake DHCP server without enabling DHCP snooping? Scenario How to block a fake DHCP se ...
- 思维 UVALive 3708 Graveyard
题目传送门 /* 题意:本来有n个雕塑,等间距的分布在圆周上,现在多了m个雕塑,问一共要移动多少距离: 思维题:认为一个雕塑不动,视为坐标0,其他点向最近的点移动,四舍五入判断,比例最后乘会10000 ...
- UVALive 6145 Version Controlled IDE(可持久化treap、rope)
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...
- UVALive 6508 Permutation Graphs
Permutation Graphs Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit ...
随机推荐
- SPOJ 3937 - Wooden Sticks 最长上升子序列LIS
给了n个(n<=5000)木棍的长度hi与宽度wi(均小于10000),现在机器要打磨这些木棍,如果相邻连个木棍hi<=hj并且wi<=wj就不需要调整机器,问如何排序使得机器调整的 ...
- SPOJ 181 - Scuba diver 二维背包
潜水员要潜水,给出n个气缸(1<=n<=1000),每个气缸中有氧气量为ti,氮气量为ai,气缸重量为wi(1<=ti<=21,1<=ai<=79,1<=wi ...
- Android中Action
1 Intent.ACTION_MAIN String: android.intent.action.MAIN 标识Activity为一个程序的开始.比较常用. <activity androi ...
- Overload和Override的区别?
Overload和Override的区别? Override是重写:方法名称.参数个数,类型,顺序,返回值类型都是必须和父类方法一致的.它的关系是父子关系Overload是重载:方法名称不变,其余的都 ...
- 哥的第一个Jquery程序
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs& ...
- JQuery中根据属性或属性值获得元素
根据属性获得元素 1.比如要获取页面p标签中属性有id的元素 $("p[id]").css("color","red"); 根据属性值获得元 ...
- 低字节序和高字节序相互转换(Little Endian/Big Endian)
这个例子展示了如何转换整形数字的字节顺序,该方法可以用来在little-endian和big-endian之间转换. 说明:Windos(x86,x64)和Linux(x86,x64)都是little ...
- Qt零基础教程(四) QWidget详解篇
在博客园里面转载我自己写的关于Qt的基础教程,没次写一篇我会在这里更新一下目录: Qt零基础教程(四) QWidget详解(1):创建一个窗口 Qt零基础教程(四) QWidget详解(2):QWid ...
- IOS 在Xcode 4.x以上添加静态库
参考网站:http://my.oschina.net/edwardlau/blog/95924 常用的代码可以通过静态库进行抽出来作为公共类方法,方便在其他地方调用,一般来说我们要准备2套静态库,一套 ...
- 【USACO 1.2.5】双重回文数
[题目描述] 如果一个数从左往右读和从右往左读都是一样,那么这个数就叫做“回文数”.例如,12321就是一个回文数,而77778就不是.当然,回文数的首和尾都应是非零的,因此0220就不是回文数. 事 ...