标签:style blog class code java ext
和上一题差不多,都是用最大流来做,可是有人能告诉我STL和直接用数组,真的有那么大区别吗?STL超时,数组0ms,这是什么数据,有那么叼吗
附上两份代码!希望过路的人能给我看看为什么会超时
STL的
#include<map> #include<set> #include<stack> #include<queue> #include<cmath> #include<vector> #include<cstdio> #include<string> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define inf 0x0f0f0f0f using namespace std; const double pi=acos(-1.0); const double eps=1e-8; typedef pair<int,int>pii; const int maxn=2500+10; struct Edge { int from,to,cap,flow; }; int n,m,s,t;//n是定点数,m是边数,s,t分别是源汇点 vector<Edge>edges; vector<int>G[maxn]; int d[maxn],cur[maxn]; bool vis[maxn]; void AddEdge(int from,int to,int cap) { Edge temp; temp.cap=cap; temp.flow=0; temp.from=from; temp.to=to; edges.push_back(temp); temp.cap=0; temp.flow=0; temp.from=to; temp.to=from; edges.push_back(temp); m=edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } bool BFS() { memset(vis,0,sizeof(vis)); queue<int>Q; Q.push(s); d[s]=0; vis[s]=1; while(!Q.empty()) { int x=Q.front();Q.pop(); for (int i=0;i<G[x].size();i++) { Edge& e=edges[G[x][i]]; if (!vis[e.to] && e.cap>e.flow) { vis[e.to]=1; d[e.to]=d[x]+1; Q.push(e.to); } } } return vis[t]; } int DFS(int x,int a) { if (x==t || a==0) return a; int flow=0,f; for (int i=cur[x];i<G[x].size();i++) { Edge& e=edges[G[x][i]]; if (d[x]+1==d[e.to] && (f=DFS(e.to,min(a,e.cap-e.flow)))>0) { e.flow+=f; edges[G[x][i]^1].flow-=f; flow+=f; a-=f; if (a==0) break; } } return flow; } int Dinic() { int flow=0; while (BFS()) { memset(cur,0,sizeof(cur)); flow+=DFS(s,inf); } return flow; } void init() { for (int i=0;i<=maxn;i++) G[i].clear(); edges.clear(); } int main() { //freopen("in.txt","r",stdin); int N,M,a,sum; int dx[4]={-1,1,0,0}; int dy[4]={0,0,-1,1}; while (scanf("%d%d",&N,&M)!=EOF) { init(); s=0;t=N*M+1; sum=0; for (int i=1;i<=N;i++) for (int j=1;j<=M;j++) { scanf("%d",&a); sum+=a; int x=(i-1)*M+j; if ((i+j)%2==0) { AddEdge(s,x,a); for (int k=0;k<4;k++) { int xx=i+dx[k]; int yy=j+dy[k]; if (xx>=1 && xx<=N && yy>=1 && yy<=M) { int y=(xx-1)*M+yy; AddEdge(x,y,inf); } } } else { AddEdge(x,t,a); for (int k=0;k<4;k++) { int xx=i+dx[k]; int yy=j+dy[k]; if (xx>=1 && xx<=N && yy>=1 && yy<=M) { int y=(xx-1)*M+yy; AddEdge(y,x,inf); } } } } printf("%d\n",sum-Dinic()); } //fclose(stdin); return 0; }
数组的
#include<map> #include<set> #include<stack> #include<queue> #include<cmath> #include<vector> #include<cstdio> #include<string> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define inf 0x0f0f0f0f using namespace std; const int N = 2500+10; const int MAX = 100000; struct Edge{ int s,e,v; int next; }edge[20*N]; int dir[4][2]={-1,0, 1,0, 0,-1, 0,1}; int n,m,e_num,head[N],d[N],sp,tp; void AddEdge(int a,int b,int c){ edge[e_num].s=a; edge[e_num].e=b; edge[e_num].v=c; edge[e_num].next=head[a]; head[a]=e_num++; edge[e_num].s=b; edge[e_num].e=a; edge[e_num].v=0; edge[e_num].next=head[b]; head[b]=e_num++; } int judge(int i,int j,int k){ int ii=i+dir[k][0]; int jj=j+dir[k][1]; if(ii>=1 && ii<=n && jj>=1 && jj<=m)return 1; return 0; } int bfs(){ queue <int> q; memset(d,-1,sizeof(d)); d[sp]=0; q.push(sp); while(!q.empty()){ int cur=q.front(); q.pop(); for(int i=head[cur];i!=-1;i=edge[i].next){ int u=edge[i].e; if(d[u]==-1 && edge[i].v>0){ d[u]=d[cur]+1; q.push(u); } } } return d[tp] != -1; } int dfs(int a,int b){ int r=0; if(a==tp)return b; for(int i=head[a];i!=-1 && r<b;i=edge[i].next){ int u=edge[i].e; if(edge[i].v>0 && d[u]==d[a]+1){ int x=min(edge[i].v,b-r); x=dfs(u,x); r+=x; edge[i].v-=x; edge[i^1].v+=x; } } if(!r)d[a]=-2; return r; } int dinic(int sp,int tp){ int total=0,t; while(bfs()){ while(t=dfs(sp,MAX)) total+=t; } return total; } int main(){ int i,j,k,a; while(~scanf("%d%d",&n,&m)) { int sum=0; e_num=0; memset(head,-1,sizeof(head)); sp=0; tp=n*m+1; for(i=1;i<=n;i++){ for(j=1;j<=m;j++){ scanf("%d",&a); sum+=a; int x=(i-1)*m+j; if((i+j)%2==0){ AddEdge(sp,x,a); for(k=0;k<4;k++){ if(judge(i,j,k)==1){//不出界 int y=(i+dir[k][0]-1)*m+(j+dir[k][1]); AddEdge(x,y,MAX);//这里要注意边的方向,是黑点向白点连边 } } } else{ AddEdge(x,tp,a); for(k=0;k<4;k++){ if(judge(i,j,k)==1){//不出界 int y=(i+dir[k][0]-1)*m+(j+dir[k][1]); AddEdge(y,x,MAX);//注意边的方向,和上面的是相反的 } } } } } int max_flow=dinic(sp,tp); printf("%d\n",sum-max_flow); } return 0; }
hdu 1569 方格取数(2),布布扣,bubuko.com
标签:style blog class code java ext
原文地址:http://www.cnblogs.com/chensunrise/p/3704413.html