BZOJ:1001狼抓兔子
简直了非常迷 看到题目毫不犹豫的写了一个网络流,然后果真就TLE了
翻了一下题解,就是最大流最小割定理然后,然后将平面图变成对偶图,相当于是从起点到终点跑一个最短路就可以了
神马居然还有这种操作??!
呃加边那个位置是挺复杂的,但是我写对了呀~
还有一个非常迷的地方就是非要用结构体来存边吗我怎么一用数组就WA啊这是什么歪理是不是BZOJ的评测机有bug
至今不知道为什么邻接表会写挂完蛋没救了
#include<cstdio> #include<iostream> #include<queue> #include<algorithm> #include<cmath> #include<cstring> #include<cstdlib> using namespace std; const int inf=0x3f3f3f3f; int n,m; int head[2000000+20]; int dis[2000000+20]; int inq[2000000+20],next[2000000],to[6000000+20]; struct node { int v,w; }e[6000000+20]; int k; int S,T; inline int RD(){ char ch; int res=0; ch=getchar(); while(ch<'0'||ch>'9')ch=getchar(); res=ch-'0'; while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-'0'; return res;}void addedge(int u,int v,int w) { next[++k]=head[u]; e[k].v=v; to[k]=e[k].v; e[k].w=w; head[u]=k; next[++k]=head[v]; e[k].v=u; to[k]=e[k].v; e[k].w=w; head[v]=k; } void spfa() { memset(dis,inf,sizeof(dis)); memset(inq,0,sizeof(inq)); queue<int>q; dis[S]=0; inq[S]=1; q.push(S); while(!q.empty()) { int now=q.front(); q.pop(); inq[now]=0; for(int i=head[now];i!=-1;i=next[i]) { int v=to[i]; v=e[i].v; if(dis[now]+e[i].w<dis[v]) { dis[v]=dis[now]+e[i].w; if(!inq[v]) { inq[v]=1; q.push(v); } } } } printf("%d\n",dis[T]); } int main() { memset(head,-1,sizeof(head)); memset(to,0,sizeof(to)); k=0; scanf("%d%d",&n,&m); if (n == 1 || m == 1) { if (n > m) swap(n, m); int ans = inf; for (int i = 1; i < m; ++i) { int x; scanf("%d",&x); if (x < ans) ans = x; } printf("%d\n", ans); exit(0); } S=0,T=2*(m-1)*(n-1)+1; int w; for(int i=1;i<=n;i++) for(int j=1;j<m;j++) if(i==1) addedge(j*2,0,RD()); else if(i==n)addedge(T,2*((i-2)*(m-1)+j)-1,RD()); else addedge(2*((i-2)*(m-1)+j)-1,2*((i-1)*(m-1)+j),RD()); for(int i=1;i<n;i++) for(int j=1;j<=m;j++) if(j==1)addedge(2*((i-1)*(m-1)+j)-1,T,RD()); else if(j==m)addedge(2*((i-1)*(m-1)+j)-2,0,RD()); else addedge(2*((i-1)*(m-1)+j)-1,2*((i-1)*(m-1)+j)-2,RD()); for(int i=1;i<n;i++) for(int j=1;j<m;j++) addedge(2*((i-1)*(m-1)+j)-1,2*((i-1)*(m-1)+j),RD()); spfa(); return 0; }

浙公网安备 33010602011771号