据说网络流写得好也能过……orz常数帝们
我自己是看了周冬的论文——他来自芜湖一中。膜拜前辈!orzzzz
S-T图直接最短路就行了,注意建图即可。
#include<cstdio> #include<vector> #include<algorithm> #include<cstring> #include<queue> using namespace std; int n,m,en,h[2000005],D[2000005],f[2000005],S,T; struct Edge{ int b,v,next; }e[7000005]; struct Node{ int u,v; bool operator< (const Node &x) const{ return v>x.v?1:0; } }; priority_queue<Node> Q; void add(int sa,int sb,int sc){ e[++en].b=sb; e[en].v=sc; e[en].next=h[sa]; h[sa]=en; } void Dijkstra(){ memset(D,120,sizeof(D)); memset(f,0,sizeof(f)); while(!Q.empty())Q.pop(); Node tmp; tmp.u=S; D[S]=0; tmp.v=0; Q.push(tmp); while(!Q.empty()){ int u=Q.top().u; Q.pop(); if(f[u])continue; if(u==T){printf("%d\n",D[T]);break;} f[u]=1; for(int i=h[u];i!=-1;i=e[i].next){ int v=e[i].b; if(!f[v] && D[u]+e[i].v<D[v]){ D[v]=D[u]+e[i].v; tmp.u=v; tmp.v=D[v]; Q.push(tmp); } } } } void Scanf(int &s){ char x; while((x=getchar())<'0' || x>'9'); s=x-'0'; while((x=getchar())>='0' && x<='9')s=s*10+x-'0'; } int main(){ freopen("1001.in","r",stdin); freopen("1001.out","w",stdout); Scanf(n); Scanf(m); S=0; T=(n-1)*(m-1)*2+1; memset(h,-1,sizeof(h)); en=0; if(n==1 || m==1){ n=max(n,m); int ans=2147483647,w; for(int i=1;i<n;i++){ Scanf(w); ans=min(ans,w); } printf("%d\n",ans==2147483647?0:ans); return 0; } for(int i=0;i<=n-1;i++){ for(int j=1;j<=m-1;j++){ int sa,sb,sc; Scanf(sc); sa=((i-1)*(m-1)+j)*2-1; sb=(i*(m-1)+j)*2; if(i==0)sa=T; else if(i==n-1)sb=S; add(sa,sb,sc); add(sb,sa,sc); } } for(int i=1;i<=n-1;i++){ for(int j=0;j<=m-1;j++){ int sa,sb,sc; Scanf(sc); sa=((i-1)*(m-1)+j)*2; sb=((i-1)*(m-1)+j+1)*2-1; if(j==0)sa=S; else if(j==m-1)sb=T; add(sa,sb,sc); add(sb,sa,sc); } } for(int i=1;i<=n-1;i++){ for(int j=1;j<=m-1;j++){ int sa,sb,sc; Scanf(sc); sa=((i-1)*(m-1)+j)*2; sb=((i-1)*(m-1)+j)*2-1; add(sa,sb,sc); add(sb,sa,sc); } } Dijkstra(); return 0; }