ASEMBL » 日志 » 网络流 SAP_再次修改
网络流 SAP_再次修改
ASEMBL 发表于 2009-10-23 21:21:14
今天卫生检查 居然通过了。。。无语
对了 我的SAP MS是比510的弱一些 但是还是发上来吧
说明:
原GAP优化有问题,因为这个是多路增广,尚有流量的情况下不能直接退出。须加GAP标记
后来发现我的sap有严重的BUG 重新提交吧 (sap于2010.7.1日修改)
其实sap递归的时候就做了3件事情:
1. 如果有可行弧,就流入
2. 如果没有,就修改标号成最小的待定可行节点标号+1
3. 如果都没有,这个点标记为无法流出
//-----------------------------------------------------有向图的SAP----------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------//
//----------------------------------------------------------------------------------------------------------------//
还做了 立体图 (很有意思的题目 2008年普及组)
贴上程序
long sap( int x , int min )
{
int flag = 0 , i , l , total = 0 , mini = ed ;
if ( x == ed )
{
ans += min;
return min;
}
for ( i = now[x] ; i && min; i = next[i] ) // 邻接表存储: g[i]表示与i节点相连的节点编号
if ( v[i] && tag[g[i]])
{
if ( num[g[i]] == num[x] - 1 )
{
l = sap( g[i] , min( min , v[i] ) );
min -= l;
total += l;
v[i] -= l;
v[back(i)] += l; // 回边的流量修改
flag = 1;
}
else
mini = min( mini , (num[g[i]]+1) );
}
if ( flag == 0 )
{
GAP[mini] ++;
GAP[num[x]] --;
if ( GAP[num[x]] == 0 )
flag_gap = false;
num[x] = mini;
}
return total;
}
#include <stdio.h>
int nn=0,mm=0;
int n,m,a[61][61]={0};
char map[601][601]={'#CONTENT#'};
char box[6][7]={
{"+---+#CONTENT##CONTENT#"},
{"| |/#CONTENT#"},
{"| | +"},
{"+---+ |"},
{"#CONTENT#/ /|"},
{"#CONTENT##CONTENT#+---+"},
};
void mem(int x,int y)
{
int i,j;
for (i=0;i<6;i++)
{
for (j=0;j<7;j++)
{
if (box[i][j]!='#CONTENT#')
map[x+i][y+j]=box[i][j];
}
}
}
void turn(int x,int y,int k)
{
int i,j,l;
for (l=1;l<=k;l++)
{
mem(x+(l-1)*3,y);
}
}
main()
{
int i,j,k,l;
int max=0;
scanf("%d%d",&n,&m);
mm=4*m+1+2*n;
for (i=1;i<=n;i++)
{
for (j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);
max=max>a[i][j]?max:a[i][j];
if (nn<(n-i)*2+1 + (a[i][j]-1)*3 + 5)
nn=(n-i)*2+1 + (a[i][j]-1)*3 + 5;
}
}
for (i=1;i<=nn;i++)
for (j=1;j<=mm;j++)
map[i][j]='.';
for (i=1;i<=n;i++)
{
for (j=1;j<=m;j++)
{
turn((n-i)*2+1,(n-i)*2+(j-1)*4+1,a[i][j]);
}
}
for (i=nn;i>0;i--)
{
for (j=1;j<=mm;j++) printf("%c",map[i][j]);
printf("\n");
}
getch();
}
//---------------------------------------------------------------------------------------------------------------------------------//
最新评论
-
2010-01-01 14:40:49
弱弱的问一句,神牛的当前弧优化在哪里啊?
我没有加当前弧优化
而且SAP千万不要写递归的 会 比ditch(非递归)还慢 -
2010-01-13 20:12:07
ditch?
神牛说的是不是dinic?
还有弱弱的问一句dinic的标号和sap的标号到底有什么不同么???
其原理都是每次找最短的路径增广么?啊 是的 我打错了 是dinic
这两个标号 一个从源点开始 一个从汇点开始
其实没有什么不同
其结果是 一个可能找多次才能找到增广路 一个可以很有效的找到增广路 -
2010-01-15 19:04:42
再弱弱地问下,神牛认为sap和dinic的效率哪个更高呢?
dinic是全能型的
sap适合稠密图 -
2010-07-29 08:22:01 匿名 10.8.*.*
神牛,sap写成递归应该不慢吧灰常快

