NOI2010 海拔

来源:互联网 发布:淘宝情趣内衣著名模特 编辑:程序博客网 时间:2024/04/27 23:45

正解是平面图转对偶图 然后跑最短路


先是题目的读入 没有说明白 导致wa


后来用最大流最小割TLE后两个点

转SPFA跑最短路 依然TLE后两个点

SPFA加上优先队列优化 才A掉


貌似更多人写heap优化的dijkstra....



注意最短路建图 由于每条边是双向的 所以一一对应到最短路的边权里去

自己画下图就能发现怎么对应



80分的最大流:

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;int id[600][600],cnt;const int MAXN=2*2*2*600*(500+1)+100;int tot=1,g[MAXN],nnext[MAXN],flow[MAXN],num[MAXN];void add(int x,int y,int z){tot++;nnext[tot]=g[x];g[x]=tot;num[tot]=y;flow[tot]=z;}void ADD(int x,int y,int z){add(x,y,z);add(y,x,0);}int d[MAXN],team[MAXN],head,tail;int s,t;bool bfs(){memset(d,0,sizeof(d));head=tail=0;team[++tail]=s;d[s]=1;while(head<tail){int x=team[++head];for(int i=g[x];i;i=nnext[i]){int tmp=num[i];if(flow[i]&&d[tmp]==0){d[tmp]=d[x]+1;team[++tail]=tmp;}}}if(d[t]==0) return 0;return true;}int dfs(int x,int mmin){if(x==t) return mmin;int f=0,tmp;for(int i=g[x];i;i=nnext[i]){if(d[num[i]]==d[x]+1&&flow[i]&&(tmp=dfs(num[i],min(flow[i],mmin)))){flow[i]-=tmp;flow[i^1]+=tmp;f+=tmp;mmin-=tmp;if(mmin==0){return f;}}}d[x]=0;return f;}int main(){int n;cin>>n;for(int i=0;i<=n;i++)for(int j=0;j<=n;j++)id[i][j]=++cnt;for(int j=0;j<=n;j++)for(int i=1;i<=n;i++){int x;scanf("%d",&x);ADD(id[j][i-1],id[j][i],x);}for(int j=1;j<=n;j++)for(int i=0;i<=n;i++){int x;scanf("%d",&x);ADD(id[j-1][i],id[j][i],x);}for(int j=0;j<=n;j++)for(int i=1;i<=n;i++){int x;scanf("%d",&x);ADD(id[j][i],id[j][i-1],x);}for(int j=1;j<=n;j++)for(int i=0;i<=n;i++){int x;scanf("%d",&x);ADD(id[j][i],id[j-1][i],x);}s=id[0][0];t=id[n][n];int ans=0;while(bfs()) ans+=dfs(s,2e9);cout<<ans<<endl;return 0;}


100分的SPFA:


#include <queue>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int MAXN = 4*500+500*500+10;const int MAXM = 4*500*(500+1)+10;int n,s,t,cnt=0;int dis[MAXN];int id[502][502];bool in[MAXN];int tot,g[MAXN],nnext[MAXM],num[MAXM],cost[MAXM];void add(int x,int y,int z){tot++;nnext[tot]=g[x];g[x]=tot;num[tot]=y;cost[tot]=z;}struct H{int x;bool operator < (const H b)const {return dis[x]>dis[b.x];}};priority_queue <H> q;int SPFA(){memset(dis,100,sizeof(dis));q.push((H){s});in[s]=true;dis[s]=0;while(q.size()){int x=q.top().x;q.pop();in[x]=false;for(int i=g[x];i;i=nnext[i]){if(dis[num[i]]>dis[x]+cost[i]){dis[num[i]]=dis[x]+cost[i];if(!in[num[i]]){q.push((H){num[i]});in[num[i]]=true;}}}}return dis[t];}int main(){cin >> n;for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) id[i][j]=++cnt;s=++cnt;t=++cnt;for(int i=1;i<=n;i++) id[0][i]=s,id[n+1][i]=t,id[i][0]=t,id[i][n+1]=s;for(int x,i=0;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&x),add(id[i][j],id[i+1][j],x);for(int x,i=1;i<=n;i++) for(int j=0;j<=n;j++) scanf("%d",&x),add(id[i][j+1],id[i][j],x);for(int x,i=0;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&x),add(id[i+1][j],id[i][j],x);for(int x,i=1;i<=n;i++) for(int j=0;j<=n;j++) scanf("%d",&x),add(id[i][j],id[i][j+1],x);cout << SPFA() << endl;return 0;}




0 0
原创粉丝点击