HDU 4888 Redraw Beautiful Drawings(网络流 + 判环(不能用强联通))

来源:互联网 发布:985软件工程硕士工资 编辑:程序博客网 时间:2024/05/18 03:13

题意和这个差不多http://blog.csdn.net/llzhh/article/details/77353532,只不过这道题改成棋盘上每个点的大小是0到k的。

建图什么的都一样,但是我发现我用一开始强联通的写法是过不去的,因为判环的地方tarjan是找极大强联通分量,这并不是我想要的,比如样例中一行四列那个。但是在上一题竟然过了。而且上一题没有判断行和列的和都相等也过了,数据实在是太水了。。。

这个判环我自己写了一个然后发现一直wa,到了下午突然发现,这都是源于多加了一个break。。。去掉就过了。。。一天又过去了。。。

判环我的方法是,dfs一下,每次进去都是在vst里面跑,如果发现某个点的vst已经标记,那么就返回1.否则我们在遍历完这个点后将他的标记擦去。这样还是怕超时,所以在外面再加上一个bvst,用于全局,如果这个点已经进去过就不再进去。。。具体还是看代码吧。。。

代码如下:

#include<bits/stdc++.h>using namespace std;const int maxn = 1005;const int maxm = maxn * maxn;const int INF = 0x3f3f3f3f;int n, m, k;int head[maxn],cur[maxn],nx[maxm<<1],to[maxm<<1],flow[maxm<<1],ppp=0;struct Dinic{int dis[maxn];int s, t;int ans;void init() {memset(head, -1, sizeof(head));ppp = 0;}void AddEdge(int u, int v, int c){to[ppp]=v;flow[ppp]=c;nx[ppp]=head[u];head[u]=ppp++;swap(u,v);to[ppp]=v;flow[ppp]=0;nx[ppp]=head[u];head[u]=ppp++;}bool BFS(){memset(dis, -1, sizeof(dis));dis[s] = 1; queue<int> Q;Q.push(s);while(!Q.empty()){int x = Q.front();Q.pop();for(int i = head[x]; ~i; i = nx[i]){if(flow[i] && dis[to[i]] == -1){dis[to[i]] = dis[x] + 1;Q.push(to[i]);}}}return dis[t] != -1;}int DFS(int x, int maxflow){if(x == t || !maxflow){ans += maxflow;return maxflow;}int ret = 0, f;for(int &i = cur[x]; ~i; i = nx[i]){if(dis[to[i]] == dis[x] + 1 && (f = DFS(to[i], min(maxflow, flow[i])))){ret += f;flow[i] -= f;flow[i^1] += f;maxflow -= f;if(!maxflow)break;}}return ret;}int solve(int source, int tank){s = source;t = tank;ans = 0;while(BFS()){memcpy(cur, head, sizeof(cur));DFS(s, INF);}return ans;}}dinic;bool vst[maxn], bvst[maxn];bool dfs(int u, int pre) {//cout << u << ' ' << pre << '\n';for(int i = head[u]; ~i; i = nx[i]) {int v = to[i];if(v == pre || flow[i] == 0)continue;if(vst[v]) {return 1;}vst[v] = 1;bvst[v] = 1;if(dfs(v, u)) {vst[v] = 0;return 1;}vst[v] = 0;}return 0;}int main() {#ifndef ONLINE_JUDGEfreopen("in.txt", "r", stdin);//    freopen("out.txt", "w", stdout);#endifwhile(scanf("%d%d%d", &n, &m, &k) != EOF) {int sum1 = 0, sum2 = 0;dinic.init();int s = n + m, t = s + 1;for(int i = 0, tmp; i < n; i++) {scanf("%d", &tmp);dinic.AddEdge(s, i, tmp);sum1 += tmp;}for(int i = 0, tmp; i < m; i++) {scanf("%d", &tmp);dinic.AddEdge(n + i, t, tmp);sum2 += tmp;}int start = ppp;for(int i = 0; i < n; i++) {for(int j = 0; j < m; j++) {dinic.AddEdge(i, n + j, k);}}int ans = dinic.solve(s, t);if(ans != sum1 || sum1 != sum2) {printf("Impossible\n");continue;}bool ok = 0;memset(bvst, 0, sizeof(bvst));for(int i = 0; i < n; i++) {if(bvst[i])continue;//memset(vst, 0, sizeof(vst));bvst[i] = 1;vst[i] = 1;if(dfs(i, i)) {ok = 1;}vst[i] = 0;}if(ok)printf("Not Unique\n");else {printf("Unique\n");for(int i = 0; i < n; i++) {for(int j = 0; j < m; j++) {printf("%d%c", k - flow[start], j + 1 == m ? '\n' : ' ');start += 2;}}}} return 0;}


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 我有c4驾驶证想办c3怎么办 驾驶证和行驶证被交警扣了怎么办 行驶证被交警弄丢了怎么办 没带行驶证让警察发现怎么办 首尔转机换票换乘怎么办过境签证 驾驶证约考帐号与登密码丢失怎么办 考驾照的时候预约密码忘了怎么办 考驾照的预约密码忘了怎么办 摩托车不能挂档不能摘挡了怎么办 身份证丢失了派出所不给挂失怎么办 快递员在中午还送货夏天怎么办啊 驾照一个记分周期扣满12分怎么办 佛山南海车管所怎么办替人消分流程 福州快处中心几流程要怎么办 被对方追尾了对方只有交强险怎么办 摩托车行驶证年检过期一年半怎么办 户口迁到杭州了身份证掉了怎么办 户口已迁至外面要补办结婚证怎么办 汽车年检时间过了1个月怎么办 户口在老家在北京工作怎么办招工 报考驾照时手机号留错了怎么办 合肥驾照换证体检没过怎么办 驾驶证记分周期到了违章未消怎么办 驾照被扣科目一过期没考怎么办 驾驶证暂扣过了换证日期怎么办? 考驾照科目二身份证丢了怎么办 驾照科目一考试身份证丢了怎么办 换驾驶证名下有车辆脱审怎么办 交警把驾驶证和行车证扣了怎么办 连续两天驾照都是扣12分怎么办? 交警开的电动车罚单丢了怎么办 驾驶证b证体检报告拖期怎么办 在中国把美国护照弄丢了怎么办 拿了驾照两年了不敢上高速怎么办 我要移民过香港大陆的驾驶证怎么办 交警开的扣行驶证的单不见了怎么办 行驶证累计记分满12分后怎么办 行车证丢了被交警查到怎么办 手机摔了一下一半黑屏了怎么办 三星手机的显示屏插头坏了怎么办? 被普通的手机维修店骗了怎么办?