题意就是有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的更多相关文章

  1. UVALive - 4108 SKYLINE[线段树]

    UVALive - 4108 SKYLINE Time Limit: 3000MS     64bit IO Format: %lld & %llu Submit Status uDebug ...

  2. UVALive - 3942 Remember the Word[树状数组]

    UVALive - 3942 Remember the Word A potentiometer, or potmeter for short, is an electronic device wit ...

  3. UVALive - 3942 Remember the Word[Trie DP]

    UVALive - 3942 Remember the Word Neal is very curious about combinatorial problems, and now here com ...

  4. 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 ...

  5. 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 ...

  6. 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 ...

  7. 思维 UVALive 3708 Graveyard

    题目传送门 /* 题意:本来有n个雕塑,等间距的分布在圆周上,现在多了m个雕塑,问一共要移动多少距离: 思维题:认为一个雕塑不动,视为坐标0,其他点向最近的点移动,四舍五入判断,比例最后乘会10000 ...

  8. UVALive 6145 Version Controlled IDE(可持久化treap、rope)

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  9. UVALive 6508 Permutation Graphs

    Permutation Graphs Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit ...

随机推荐

  1. COGS 908 校园网

    /* Tarjan缩点之后 强联通分量建图 统计每个强联通分量的出入度 第一问就是入度为0的 强联通分量的个数 第二问 为了高效的使每个强联通分量都有出入度 要把出度为零的强联通分量连到入度为零的点上 ...

  2. Android比较实用的属性

    ImageView //设置图片填充整个背景 android:scaleType="fitXY"

  3. java org.apache.struts.taglib.html.BEAN 没有找到

    index.jsp <body> <a href="login2.do">登陆(struts标签)</a><br> </bod ...

  4. ASP.NET5配置

    ASP.NET5支持各种各样的配置,应用程序配置数据可以来自JSON, XML或者INI格式的文件,也能来自环境变量,你也可以自定义你自己的Configuration Provider. 1. 获取和 ...

  5. linux 'more' command.

    more命令,功能类似 cat ,cat命令是整个文件的内容从上到下显示在屏幕上. more会以一页一页的显示方便使用者逐页阅读,而最基本的指令就是按空白键(space)就往下一页显示,按 b 键就会 ...

  6. iOS开发之四张图说明GCD(Grand Central Dispatch)附Test源码

    首先,先介绍几个概念:GCD,队列,串行,并行,同步,异步.                                                                       ...

  7. 使用<a>标签,链接到另一个页面

    使用<a>标签可实现超链接,它在网页制作中可以说是无处不在,只要有链接的地方,就会有这个标签. 语法: <a href="目标网址" title="鼠标 ...

  8. 六、C# 派生

    派生 对一个现有的类型进行扩展,以便添加更多的功能,或者对现有的类型的操作进行重写.   比如可以将两个类都适用的方法和属性,用一个新的类进行重构,两个类再分别继承这个类.   定义一个派生类时,要在 ...

  9. 限制窗口拉伸范围——WM_GETMINMAXINFO

    注意:此方法对CListCtrl的Report模式下的表头绘制有影响,用时需注意测试! 使用OnSizing的改进版 该例程用处为将窗口限制了大小,并且只允许上下拉伸.需要注意的是WM_GETMINM ...

  10. c#中使用ABCpdf处理PDF

    using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.UI ...