最开始写费用流的时候,有且只会SPFA版的费用流,而且一直都够用,一般来说只要建出了图就赢了,网络流怎么都不会超时。
。。。。这个情况到今天被终结了。。。
终结者见下:
--------------------------------------------------------------------------------------------------------
最优图像
【题目描述】
小E在好友小W的家中发现一幅神奇的图画,对此颇有兴趣。它可以被看做一个包含N×M个像素的黑白图像,为了方便起见,我们用0表示白色像素,1表示黑色像素。小E认为这幅图画暗藏玄机,因此他记录下了这幅图像中每行、每列的黑色像素数量,以回去慢慢研究其中的奥妙。
有一天,小W不慎将图画打湿,原本的图像已经很难分辨。他十分着急,于是找来小E,希望共同还原这幅图画。根据打湿后的图画,他们无法确定真正的图像,然而可以推测出每个像素原本是黑色像素的概率Pij%。那么,一个完整的图像的出现概率就可以定义为
,其中Sij表示在还原后的图像中,像素是白色(0)还是黑色(1)。换句话说,一个完整图像出现概率就等于其所有黑色像素的出现概率之积。显然,图像的黑色像素不能包含概率为0的像素。
然而,小E对此也无能为力。因此他们找到了会编程的小F,也就是你,请你根据以上信息,告诉他们最有可能是原始图像的答案是什么。
【输入文件】
输入文件image.in的第一行是两个正整数N和M,表示图像大小。
接下来N行每行包含M个整数,表示每个像素是黑色像素的概率为Pij%。0 ≤ Pij < 100。
接下来一行有N个非负整数,表示每一行中黑色像素的个数。
接下来一行有M个非负整数,表示每一列中黑色像素的个数。
【输出文件】
输出文件image.out包含一个N×M的01矩阵,表示你还原出的图像。输出不包含空格。图像每行、每列中1的个数必须与输入一致,且是所有可能的图像中出现概率最大的一个。输入数据保证至少存在一个可能的图像。如果有多种最优图像,任意输出一种即可。
【样例输入】
2 2
90 10
20 80
1 1
1 1
【样例输出】
10
01
【样例解释】
共有两种可能的图像:
01
10
和
10
01
前者的出现概率是0.1×0.2=0.02,后者的出现概率是0.9×0.8=0.72,故后者是最优图像。
【数据规模和约定】
对于20%的数据,N , M ≤ 5;
对于100%的数据,N , M ≤ 100。
--------------------------------------------------------------------------------------------------------
这道题的时限是两秒。
这道题的做法是把行和列拿出来,如果i行j列出现1的就把i行与j列连一条流量为1,费用为log(p[i][j])的边。源与每行、每列与汇都连一条流量为行、列1的个数,费用为0的边,然后求最大费用最大流。流过的边所连的行和列的交点就有一个点。
当时看到n<=100,总点数就是2n,心想很小。。。但没想到边有10000条,用SPFA写出来了过后开始只有60分。。后来优化到了70分,就是SPFA极限了,剩下的点根本进不了2秒。
SPFA的时间复杂度是O(km)的,m是边数,k是常数,在这题特殊的图里面一次只能增广1的流量。。所以总的时间复杂度达到了O(100*100*O(SPFA)) > 100000000。。。
于是没办法,把zkw的网络流学了。。
其实zkw网络流增广的时候是sap,修改标号的时候是KM。。。。所以学起来很顺畅,写起来也比SPFA的短,但是效率要高很多:
膜拜啊!
代码:
1
/**//*
2
* $File: costflow.cpp
3
*/
4
5
#include <iostream>
6
#define MAXNODE 500
7
#define MAXEDGE MAXNODE*MAXNODE
8
#define MIN(a,b) ((a)<(b)?(a):(b))
9
#define OPPOSITE(x) (((x)&1)?((x)+1):((x)-1))
10 #define INFINIT ~0U>>1
11
12
using namespace std;
13
14
15
int n,m;
16
int N,S,T;
17
int begin[MAXNODE+1],end[MAXEDGE+1],next[MAXEDGE+1],c[MAXEDGE+1],cost[MAXEDGE+1],d[MAXNODE+1],cur[MAXNODE+1];
18
bool hash[MAXNODE+1];
19
int Count = 0;
20
int aug(int u,int f)
{
21
if (u == T) return f;
22
hash[u] = true;
23
for (int now = cur[u]; now; now = next[now])
24
if (c[now]&&!hash[end[now]]&&d[u] == d[end[now]]+cost[now])
25
if (int tmp = aug(end[now],MIN(f,c[now])))
26
return c[now] -= tmp,c[OPPOSITE(now)] += tmp,cur[u] = now,tmp;
27
return 0;
28
}
29
bool modlabel()
{
30
int tmp = INFINIT;
31
for (int i = 1; i<=N; i++)
32
if (hash[i])
33
for (int now = begin[i]; now; now = next[now])
34
if (c[now]&&!hash[end[now]])
35
tmp = MIN(tmp,d[end[now]]+cost[now]-d[i]);
36
if (tmp == INFINIT)
37
return true;
38
for (int i = 1; i<=N; i++)
39
if (hash[i])
40
hash[i] = false,d[i] += tmp;
41
return false;
42
}
43
int CostFlow()
{
44
int costflow = 0,tmp;
45
while (true)
{
46
for (int i = 1; i<=N; i++)
47
cur[i] = begin[i];
48
while (tmp = aug(S,~0U>>1))
{
49
costflow += tmp*d[S];
50
memset(hash,0,sizeof(hash));
51
}
52
if (modlabel())
53
break;
54
}
55
return costflow;
56
}
57
void AddEdge(int a,int b,int flow, int v)
{
58
Count++; next[Count] = begin[a]; begin[a] = Count; end[Count] = b; c[Count] = flow; cost[Count] = v;
59
Count++; next[Count] = begin[b]; begin[b] = Count; end[Count] = a; c[Count] = 0; cost[Count] = -v;
60
}
61
int main()
{
62
freopen("costflow.in","r",stdin);
63
freopen("costflow.out","w",stdout);
64
scanf("%d%d",&n,&m);
65
while (m--)
{
66
int t1,t2,t3,t4;
67
scanf("%d%d%d%d",&t1,&t2,&t3,&t4);
68
AddEdge(t1,t2,t3,t4);
69
}
70
S = 1,T = N = n;
71
printf("%d\n",CostFlow());
72
return 0;
73
}
74
75
今天先休息一下,整理一下思路有时间再详细写下过程~