hdu4888 最大流(构造矩阵)
题意:
让你构造一个矩阵,满足每一行的和,和每一列的和都等于他给的,还要判断答案是否唯一,还有一点就是矩阵内所有的数字都是[0,k]范围的。
思路:
这个题目看完就让我想起了hdu3338,那个题目做了好久啊!哎!对于构造矩阵还是很简单的,我们构造两个点起s点和终点e,建图如下:
s -> 所有行 流量是当前行和
所有行 -> 所有列 流量为k
所有列 -> e 流量为当前列和
这样矩阵就构造好了,如果输出答案就直接去残余网络里面找就行了,下面说一下怎么判断最大流是否唯一,其实这个我们可以通过残余网络来找,只要能在残余网络上找到环就行了,这个结论值存在于无环图中,这里说的无环图是指建图的时候的正向图是无环的,对于这个题目就是无环图,这个题目还有一个坑点,就是一开始我是从终点开始搜直接找环,没有从起点是因为起点已经满流,正向流量全是0,根本跑不懂,但是从终点跑各种超时,超时出翔了,无语了我又枚举所有终点所连接的点开始跑,还是超时,最后是枚举起点所连接的点
开始跑的,500ms AC,我有点蛋疼,理论上对于一个环而言从哪个位置跑都可以找到环,我估计是数据里面给的 "能得到唯一答案" 的数据过多,这样就让很多正向的流量变成0,或者是不至于走了好几层才变成0,哎!这个不科学啊!
#include<stdio.h>
#include<string.h>
#include<queue> #define N_node 810
#define N_edge 350000
#define INF 1000000000
using namespace std; typedef struct
{
int to ,next ,cost;
}STAR; typedef struct
{
int x ,t;
}DEP; STAR E[N_edge];
DEP xin ,tou;
int list[N_node] ,list1[N_node] ,tot;
int deep[N_node] ,map[405][405]; void add(int a ,int b ,int c)
{
E[++tot].to = b;
E[tot].cost = c;
E[tot].next = list[a];
list[a] = tot;
E[++tot].to = a;
E[tot].cost = 0;
E[tot].next = list[b];
list[b] = tot;
} int minn(int x ,int y)
{
return x < y ? x : y;
} bool bfs_deep(int s ,int t ,int n)
{
xin.x = s ,xin.t = 0;
queue<DEP>q; q.push(xin);
memset(deep ,255 ,sizeof(deep));
deep[s] = 0;
while(!q.empty())
{
tou = q.front();
q.pop();
for(int k = list[tou.x] ;k ;k = E[k].next)
{
xin.x = E[k].to;
xin.t = tou.t + 1;
if(deep[xin.x] == -1 && E[k].cost)
{
deep[xin.x] = xin.t;
q.push(xin);
}
}
}
for(int i = 0 ;i <= n ;i ++)
list1[i] = list[i];
return deep[t] != -1;
} int DFS(int s ,int t ,int flow)
{
if(s == t) return flow;
int nowflow = 0;
for(int k = list1[s] ;k ;k = E[k].next)
{
list1[s] = k;
int c = E[k].cost;
int to = E[k].to;
if(!c || deep[to] != deep[s] + 1) continue;
int tmp = DFS(to ,t ,minn(c ,flow - nowflow));
nowflow += tmp;
E[k].cost -= tmp;
E[k^1].cost += tmp;
if(nowflow == flow) break;
}
if(!nowflow) deep[s] = 0;
return nowflow;
} int DINIC(int s ,int t ,int n)
{
int ans = 0;
while(bfs_deep(s ,t ,n))
{
ans += DFS(s ,t ,INF);
}
return ans;
} int mark_r;
int mark[N_node];
void DFS_R(int from ,int s)
{
for(int k = list[s] ;k && !mark_r ;k = E[k].next)
{
int to = E[k].to;
if(k == (from ^ 1) || !E[k].cost) continue;
if(mark[to]) mark_r = 1;
mark[to] = 1;
if(!mark_r) DFS_R(k ,to);
mark[to] = 0;
}
} int main ()
{
int n ,m ,i ,j ,k ,num;
int s1 ,s2;
while(~scanf("%d %d %d" ,&n ,&m ,&k))
{
memset(list ,0 ,sizeof(list)) ,tot = 1;
int mkk = 0;
for(s1 = 0 ,i = 1 ;i <= n ;i ++)
{
scanf("%d" ,&num);
add(0 ,i ,num);
if(k * m < num) mkk = 1;
s1 += num;
}
for(s2 = 0 ,i = 1 ;i <= m ;i ++)
{
scanf("%d" ,&num);
add(i + n ,n + m + 1 ,num);
if(k * n < num) mkk = 1;
s2 += num;
}
if(s1 != s2 || mkk)
{
puts("Impossible"); continue;
}
int mk = tot + 1;
for(i = 1 ;i <= n ;i ++)
for(j = 1 ;j <= m ;j ++)
add(i ,j + n ,k);
int sum = DINIC(0 ,n + m + 1 ,n + m + 1);
if(sum != s1)
{
puts("Impossible"); continue;
}
mark_r = 0;
memset(mark , 0 ,sizeof(mark));
mark[n+m+1] = 1;
for(i = 1 ;i <= n ;i ++)
{
DFS_R(0 ,i);
if(mark_r) break;
}
if(mark_r)
{
puts("Not Unique");continue;
}
puts("Unique");
int t = 0;
for(i = mk ;i <= tot ;i += 2)
{
printf("%d" ,k - E[i].cost);
if(++t % m == 0) puts("");
else printf(" ");
}
}
return 0;
}
hdu4888 最大流(构造矩阵)的更多相关文章
- hdu4975 行列和构造矩阵(dp判断唯一性)
题意: 和hdu4888一样,只不过是数据加强了,就是给你行列的和,让你构造一个矩阵,然后判断矩阵是否唯一. 思路: 构造矩阵很简单,跑一次最大流就行了,关键是判断矩阵的唯一性 ...
- POJ 2396 构造矩阵(上下流)
题意: 要求构造一个矩阵,给你行和,列和,还有一些点的上下范围,输出一个满足题意的矩阵. 思路: 这个题目很经典,这是自己看上下流后接触的第一道题,感觉很基础的一道题目,现在我 ...
- POJ 3233 Matrix Power Series(构造矩阵求等比)
Description Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak. ...
- Number Sequence(HDU 1005 构造矩阵 )
Number Sequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
- hdu 5015 233 Matrix(构造矩阵)
http://acm.hdu.edu.cn/showproblem.php?pid=5015 由于是个二维的递推式,当时没有想到能够这样构造矩阵.从列上看,当前这一列都是由前一列递推得到.依据这一点来 ...
- [数学-构造矩阵]NEFU 1113
依据题意.我已经推导出tn的公式.ti=ti.a+ti.b,ti.a=5*t(i-1).a+4*t(i-1).b,ti.b=t(i-1).a+t(i-1).b 然而以下居然不能继续推到sn的公式!!! ...
- poj 3735 Training little cats(构造矩阵)
http://poj.org/problem?id=3735 大致题意: 有n仅仅猫,開始时每仅仅猫有花生0颗,现有一组操作,由以下三个中的k个操作组成: 1. g i 给i仅仅猫一颗花生米 2. e ...
- HDU 3306 Another kind of Fibonacci ---构造矩阵***
Another kind of Fibonacci Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- 构造矩阵解决这个问题 【nyoj299 Matrix Power Series】
矩阵的又一个新使用方法,构造矩阵进行高速幂. 比方拿 nyoj299 Matrix Power Series 来说 给出这样一个递推式: S = A + A2 + A3 + - + Ak. 让你求s. ...
随机推荐
- [个人总结]利用grad-cam实现人民币分类
# -*- coding:utf-8 -*- import os import numpy as np import torch import cv2 import torch.nn as nn fr ...
- AtCoder Beginner Contest 194
A I Scream int main() { IOS; int a, b; cin >> a >> b; if(a + b >= 15 && b > ...
- Python爬虫学习一------HTTP的基本原理
昨天刚买的崔大大的<Python3网络爬虫开发实战>,今天就到了,开心的读完了爬虫基础这一章,现记录下自己的浅薄理解,如有见解不到位之处,望指出. 1.HTTP的基本原理 ①我们经常会在浏 ...
- 强制断开ssh连接出现ssh崩溃问题
出现原因 finalshell意外终止,导致ssh连接意外终止 之后怎么都连不上虚拟机的ssh,一看是虚拟机的ssh已经被意外暂停,可能是跟finalshell的意外终止有关 解决 chmod 600 ...
- AbstractQueuedSynchronizer之AQS
一.可重入锁 可参考:可重入锁和递归锁 1,定义 指的是同一线程外层函数获得锁后,再进入该线程的内层方法会自动获取锁(前提:锁对象是同一个对象). Java中的ReentranLock(显示锁)和Sy ...
- Java基础知识-简明阐述双亲委派机制及作用
1.双亲委派机制及作用 1.1 什么是双亲委派机制 当某个类加载器需要加载某个.class文件时,它首先把这个任务委托给他的上级类加载器,递归这个操作,如果上级的类加载器没有加载,自己才会去加载这个类 ...
- springboot源码解析-管中窥豹系列之BeanPostProcessor(十二)
一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...
- 一次VLAN标签引发的网络事件的处置
一次VLAN标签引发的网络事件的处置 一.背景介绍 事件背景: HZ某分公司新装一套业务系统,通过一条专线和BJ总公司连通.分配给HZ公司的ip地址为:a.b.c.X,掩码24位,网关a.b.c.1. ...
- Ubuntu18.04美化(Mac OS主题) 美化小白专用
本文主要针对第一次接触Ubuntu美化的童鞋们,有些啰嗦的地方大神勿喷 先上效果图 首先安装神器 gnome-tweak-tool 开启一个终端,输入 sudo apt install gnome-t ...
- PHP并发抢购解决方案
Mysql版 逻辑步骤 mysql存储引擎使用Innodb 开始事务,查询商品库存并加上共享锁 判断库存是否足够,进行商品/订单/用户等操作 提交事务,完成下单抢购 代码参考 // 关闭自动提交 $t ...