hdu 4862解题报告
来源:互联网 发布:java web 开发 编辑:程序博客网 时间:2024/05/21 22:33
看完题写了个暴搜,果断T了..dp的话复杂度太高了,只能用网络流求解
仔细分析是一个费用流的模型,把费用取负就可以用最小费用流来跑了
费用流中的每条流就对应每次无限制的jump,按规则连好边
关键问题就是如何让所有点都被访问一次:拆点后设流量为1,费用为-10*10*10(不可能达到的能量)
还有就是设两个超级原点S和S',让S和S'直接的流量为K,费用为0,再让S'连向所有结点的入点(保证最多有K条流)
最后是费用流算法...开始上的zkw,跑不出正解...换了个spfa暴力费用流居然直接过了(好像zkw不能处理负cost的?)
#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <queue>using namespace std;const int maxm=20000;const int maxn=10*10*10;const int inf=0x3f3f3f3f;const int ddd=10*10*10;const int S=0,T=1;int N,M,K;int NN;char arr[11][11];struct EDGE{ int to,next,cap,cost,from;};EDGE edge[maxm];int box[maxn];int ent;void _add(int f,int t,int cap,int cost){ edge[ent].cap=cap; edge[ent].cost=cost; edge[ent].to=t; edge[ent].from=f; edge[ent].next=box[f]; box[f]=ent++;}void add(int f,int t,int cap,int cost){ _add(f,t,cap,cost); _add(t,f,0,-cost);}int getp(int x,int y){ return (x*M+y)*2+2;}int in[maxn];int dis[maxn];int from[maxn];queue<int> que;bool spfa(int f,int t){ int now; for(int i=0; i<NN; i++) dis[i]=inf; memset(in,0,sizeof(in)); memset(from,-1,sizeof(from)); que.push(f); in[f]=1; dis[f]=0; while(!que.empty()) { now=que.front(); que.pop(); for(int i=box[now]; i!=-1; i=edge[i].next) { if(edge[i].cap&&dis[edge[i].to]>dis[now]+edge[i].cost) { dis[edge[i].to]=dis[now]+edge[i].cost; from[edge[i].to]=i; if(!in[edge[i].to]) { que.push(edge[i].to); in[edge[i].to]=1; } } } in[now]=0; } if(dis[t]==inf) return 0; return dis[t];}int fyl(int f,int t){ int cost=0; int mincap; while(spfa(f,t)) { mincap=inf; for(int i=from[t]; i!=-1; i=from[edge[i].from]) mincap=min(mincap,edge[i].cap); for(int i=from[t]; i!=-1; i=from[edge[i].from]) { edge[i].cap-=mincap; edge[i^1].cap+=mincap; } cost+=dis[t]*mincap; } return cost;}void buildMap(){ ent=0; memset(box,-1,sizeof(box)); NN=N*M*2+5; int SS=N*M*2+4; add(S,SS,K,0); for(int i=0; i<N; i++) for(int j=0; j<M; j++) { add(getp(i,j),getp(i,j)+1,1,-ddd); add(SS,getp(i,j),1,0); add(getp(i,j)+1,T,1,0); for(int k=i+1; k<N; k++) { add(getp(i,j)+1,getp(k,j),1,(k-i-1)-(arr[i][j]==arr[k][j]?arr[i][j]-'0':0)); } for(int k=j+1; k<M; k++) { add(getp(i,j)+1,getp(i,k),1,(k-j-1)-(arr[i][j]==arr[i][k]?arr[i][j]-'0':0)); } }}int main(){ freopen("in.txt","r",stdin); int T; scanf("%d",&T); for(int cas=1; cas<=T; cas++) { printf("Case %d : ",cas); scanf("%d%d%d",&N,&M,&K); for(int i=0; i<N; i++) for(int j=0; j<M; j++) cin>>arr[i][j]; if(K<min(N,M)) { printf("-1\n"); continue; } buildMap(); printf("%d\n",-fyl(0,1)-N*M*ddd); } return 0;}
0 0
- hdu 4862解题报告
- HDU 3342 解题报告
- HDU 3336 解题报告
- HDU 3335 解题报告
- hdu 2516解题报告
- hdu 1004解题报告
- hdu 2139解题报告
- hdu 1019解题报告
- hdu 1064 解题报告
- HDU 1113 解题报告
- hdu 1068 解题报告
- HDU:2050解题报告
- hdu 4001解题报告
- hdu 1005解题报告
- HDU解题报告--1003
- HDU解题报告--1004
- HDU解题报告--1005
- HDU 1005 解题报告
- vs2012编译gtest错误error C2955
- 剑指offer 3.4 代码的鲁棒性1- 链表中倒数第K个节点
- Android 学习历程摘要(一)
- 使用socket.io和node.js搭建websocket应用
- FileStream 的FileShare一点小认识
- hdu 4862解题报告
- android学习--视图列表(ListView和ListActivity)
- poj1598(字符串处理)
- 【九度OJ】1029【HashMap查找】
- 每天一个Linux命令
- Code Review(一)
- MySQL索引类型总结和使用技巧以及注意事项
- POJ 1062 昂贵的聘礼
- 封装 ASIHTTPRequest 多请求管理类