吐槽 isap/ 轉dinic

  

       經典問題:方格取數,二分圖的最大權獨立集,直接把我的isap卡的天崩地裂。。。。。。

      

        >.<!話說當時寫現在用的程序是以前看了某某的博客,加上YY了一頓,no 當前弧優化, 單路增廣,遞歸版。。。。。。僅僅加了個gap優化>.<

        就這樣還是擠過了秋哥的“最大流強數據”,還踩掉了hyc的多路增廣dinic = 。 =!結果這次一個普通的二分圖就把我卡了。。。。。。

        

         以前那個醜程序就不貼了=。=!

 

         熱烈祝賀 從遞歸版單路增廣無當前弧isap  轉變爲 非遞歸版多路增廣加當前弧dinic(轉變真大), 感謝lzn 提供程序,以及lyp,hyc 提供不同的代碼對比長度。

  

         3個過程一共37 行,無奇葩縮行,很好理解。 

     速度快,空間小,代碼短,真可謂是居家旅行之必備呀.

# include <cstdlib>
# include <cstdio>
# include <cmath>
#include <ctime>
#include <cstring>
using namespace std;

const int maxn = 110, maxm = 105000, oo=1073741819;
int top, next[maxm*2], point[maxm*2], linke[maxm*2], wis[maxm*2], a[maxn][maxn];
int tot, p, tab[maxm], prev[maxm], shift[maxm], flow, s, t, maxflow, n, m;
int mx[10], my[10];
int l, r, que[maxm], step[maxm], adm[maxm];
bool flag;
 
inline int min(int x, int y){return x<y?x:y;};
void link(int x, int y, int z)
{
	++top; next[top] = linke[x]; linke[x] = top; point[top] = y; wis[top] = z;
	++top; next[top] = linke[y]; linke[y] = top; point[top] = x; wis[top] = 0;
}

bool bfs()
{
	memset(tab, -1, sizeof(tab));
	int l = 1, r = 1; que[l] = s; tab[s] = 1;
	for (;l <= r;l++)
	  for (int ke = linke[que[l]]; ke; ke = next[ke])
      {
	    if (tab[point[ke]]==-1 && wis[ke])
	      tab[que[++r] = point[ke]] = tab[que[l]] + 1;
	    if (que[r] == t) return true;
	  }
	return false;
}

void improve()
{
	flow = oo;
	for (int x = prev[t]; x ;x = prev[x])
	  if (wis[shift[x]] < flow) p = x, flow = wis[shift[x]];
	for (int x = prev[t]; x ;x = prev[x])
	  wis[shift[x]] -= flow, wis[shift[x]^1] += flow;
	maxflow += flow;
}
void dfs()
{
	memcpy(shift, linke, sizeof(shift));
	for (int x = s, y;x ;)
	{
		int flag = false;
		for (int ke = shift[x]; ke; ke = next[ke])
		  if (wis[ke] && (tab[y = point[ke]] == tab[x] + 1))
		  {
				prev[y] = x; shift[x] = ke; x = y; flag = true;
				if (x == t) improve(), x = p;
				if (flag) break;
		  }
		if (!flag) tab[x] = -1,x = prev[x]; 
	}
}
int main()
{
	int i, j, k, ii, jj;
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	scanf("%d%d",&n, &m); top = 1;
	mx[1]=1; mx[2]=0; mx[3]=-1; mx[4]=0;
	my[1]=0; my[2]=1; my[3]=0; my[4]=-1;
	for (i = 1; i <= n; i++)
	  for (j = 1; j <= m; j++)
	    scanf("%d", &a[i][j]), tot+= a[i][j];
	s = n*m+1; t = s+1;
	for (i = 1; i <= n; i++)
	  for (j = 1; j <= m; j++)
	    if (i+j&1) 
		   link(s, (i-1)*m+j, a[i][j]);
	    else 
		   link((i-1)*m+j, t, a[i][j]);
	for (i = 1; i <= n; i++)
	  for (j = 1; j <= m; j++)
	   if (i+j&1)
	    for (k = 1; k <= 4; k++)
	    {
			ii = i+mx[k]; jj= j+my[k];
			if (ii>=1&&ii<=n&&jj>=1&&jj<=m) link((i-1)*m+j, (ii-1)*m+jj, oo);
		}
	memcpy (adm, linke, sizeof(adm));
	while ( bfs()) 
	  dfs();
	printf("%d", tot-maxflow);
	return 0;
}


          話說考場上看出來問題是一個二分圖最大權獨立集的模型,但是不會算法=。=! 下星期強力強力惡補圖論!!!!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章