网络流 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();
}
//---------------------------------------------------------------------------------------------------------------------------------//

 

关键词(Tag): 信息学 网络流 c语言 sap

最新评论

  • 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适合稠密图


  • ylfdrib
    2010-07-29 08:22:01 匿名 10.8.*.*

    神牛,sap写成递归应该不慢吧

    灰常快

发表评论

*昵称

已经注册过? 请登录

Email
网址
*评论