hdu3338 类似数独 网络流dinic(关于行列建图的巧妙)

边容量即为所填数

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<algorithm>
  4 #include<queue>
  5 using namespace std;
  6 #define inf 0x3f3f3f3f
  7 struct Edge
  8 {
  9     int from,to,cap,flow;
 10     int x,y,dian,judge;
 11 };
 12 vector<Edge>edges;
 13 vector<int>G[50005];
 14 int s,t,vis[50005],d[50005],cur[50005],map[105][105];
 15 int min(int x,int y)
 16 {
 17     if (x<y) return x;
 18     return y;
 19 }
 20 void addadge(int from,int to,int cap,int x,int y,int judge)
 21 {
 22     Edge edge1;
 23     edge1.from=from; edge1.to=to; edge1.cap=cap; edge1.flow=0;
 24     edge1.x=x; edge1.y=y; edge1.judge=judge;
 25     edges.push_back(edge1);
 26     edge1.from=to; edge1.to=from; edge1.cap=0; edge1.flow=0;
 27     edge1.x=x; edge1.y=y; edge1.judge=-judge;
 28     edges.push_back(edge1);
 29     int m=edges.size();
 30     G[from].push_back(m-2);
 31     G[to].push_back(m-1);
 32 }
 33 int bfs()
 34 {
 35     memset(vis,0,sizeof(vis));
 36     queue<int>q;
 37     while (!q.empty()) q.pop();
 38     q.push(s); d[s]=0; vis[s]=1;
 39     while (!q.empty())
 40     {
 41         int x=q.front(); q.pop();
 42         for (int i=0;i<G[x].size();i++)
 43         {
 44             Edge& e=edges[G[x][i]];
 45             if (!vis[e.to]&&e.cap>e.flow)
 46             {
 47                 vis[e.to]=1; d[e.to]=d[x]+1;
 48                 q.push(e.to);
 49             }
 50         }
 51     }
 52     return vis[t];
 53 }
 54 int dfs(int x,int a)
 55 {
 56     if (x==t||a==0) return a;
 57     int flow=0,f;
 58     for (int& i=cur[x];i<G[x].size();i++)
 59     {
 60         Edge& e=edges[G[x][i]];
 61         if (d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0)
 62         {
 63             e.flow+=f;
 64             edges[G[x][i]^1].flow-=f;
 65             flow+=f; a-=f;
 66             if (a==0) break;
 67         }
 68     }
 69     return flow;
 70 }
 71 int main()
 72 {
 73     int maxflow,i,j,n,m,kk,xx,yy,x,y,dian,cnt;
 74     char st[10];
 75     while (~scanf("%d%d",&n,&m))
 76     {
 77         edges.clear();
 78         for (i=0;i<=2*n*m+1;i++) G[i].clear();
 79         s=0; t=2*n*m+1;
 80         memset(map,0,sizeof(map));
 81         for (i=1;i<=n;i++)
 82          for (j=1;j<=m;j++)
 83          {
 84              scanf("%s",st);
 85              if (st[0]!='.')
 86              {
 87                  map[i][j]=1;
 88                  if (st[0]!='X')
 89                  {
 90                      kk=(st[0]-'0')*100+(st[1]-'0')*10+st[2]-'0';
 91                      addadge(n*m+(i-1)*m+j,t,kk,i,j,4);
 92                  }
 93                  if (st[4]!='X')
 94                  {
 95                      kk=(st[4]-'0')*100+(st[5]-'0')*10+st[6]-'0';
 96                      addadge(s,(i-1)*m+j,kk,i,j,1);
 97                  }
 98              }
 99          }
100          for (i=0;i<edges.size();i++)
101          {
102              xx=edges[i].x; yy=edges[i].y;
103              if (edges[i].judge==1)
104              {
105                  dian=edges[i].to; cnt=0;
106                  for (y=yy+1;y<=m&&map[xx][y]==0;y++)
107                  {
108                      addadge(dian,(xx-1)*m+y,8,xx,y,2);
109                      cnt++;
110                  }
111                  edges[i].cap-=cnt;
112              }
113              else if (edges[i].judge==4)
114              {
115                  dian=edges[i].from; cnt=0;
116                  for (x=xx+1;x<=n&&map[x][yy]==0;x++)
117                  {
118                      addadge((x-1)*m+yy,dian,8,x,yy,3);
119                      cnt++;
120                  }
121                  edges[i].cap-=cnt;
122              }
123          }
124          maxflow=0;
125          while (bfs())
126          {
127              memset(cur,0,sizeof(cur));
128              maxflow+=dfs(s,inf);
129          }
130          memset(map,0,sizeof(map));
131          for (i=0;i<edges.size();i++)
132          if (edges[i].judge==3) map[edges[i].x][edges[i].y]=edges[i].flow+1;
133          for (i=1;i<=n;i++)
134          {
135              for (j=1;j<m;j++)
136               if (map[i][j]) printf("%d ",map[i][j]);
137               else printf("_ ");
138              if (map[i][m]) printf("%d\n",map[i][m]);
139              else printf("_\n");
140          }
141       }
142 }

http://acm.hdu.edu.cn/showproblem.php?pid=3338

转载于:https://www.cnblogs.com/xiao-xin/articles/3919529.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值