思路:在把乘机转化成对数相加的形式,能够看到要消灭一个外星人,要么在他所在的行上放一把武器,要么在他所在列上放一把武器,因此能够在源点s和行x上连一条log(w)的边,在列和汇点t上连一条log(w)的边,在外星人的坐标x和y+n之间连一条INF的边。由于增广的时候满足流量限制所以会选择最小的代价。
只是还是wa了非常久。。原因就是用个g++提交,输出的时候使用了%lf,后来改成%f了还是wa,后来发现关闭了c++和c的输入输出同步,但任然在混用输入。。取消关闭之后就ac了。。。所以建议没事还是不要混用输入输出了
代码例如以下:
/************************************************************************* > File Name: c.cpp > Author: acvcla > QQ: > Mail: [email protected] > Created Time: 2014年10月13日 星期一 22时26分17秒 ************************************************************************/ #include<iostream> #include<algorithm> #include<cstdio> #include<vector> #include<cstring> #include<map> #include<queue> #include<stack> #include<string> #include<cstdlib> #include<ctime> #include<set> #include<math.h> using namespace std; typedef long long LL; const int maxn = 5e2 + 30; const int INF =1e7; #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define pb push_back int n,m,s,t,l; int d[maxn],cur[maxn]; struct Edge { int from,to; double cap,flow; }; std::vector<int>G[maxn]; std::vector<Edge>edges; void init(int n){ for(int i=0;i<=n;i++)G[i].clear(); edges.clear(); } void addEdge(int u,int v,double w) { edges.pb((Edge){u,v,w,0}); edges.pb((Edge){v,u,0.0,0}); int sz=edges.size(); G[u].pb(sz-2); G[v].pb(sz-1); } int bfs(){ memset(d,0,sizeof d); queue<int>q; q.push(s); while(!q.empty()){ int u=q.front();q.pop(); for(int i=0;i<G[u].size();i++){ Edge &e=edges[G[u][i]]; if(e.to==s)continue; if(!d[e.to]&&e.cap>e.flow){ q.push(e.to); d[e.to]=d[u]+1; } } } return d[t]; } double dfs(int u,double a) { if(u==t||a==0.0)return a; double flow=0.0,f=0.0; for(int &i=cur[u];i<G[u].size();++i){ Edge &e=edges[G[u][i]]; if(d[e.to]==d[u]+1&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0.0){ e.flow+=f; edges[G[u][i]^1].flow-=f; flow+=f; a-=f; if(a==0.0)break; } } return flow; } double Dinic(){ double flow=0; while(bfs()){ memset(cur,0,sizeof cur); flow+=dfs(s,INF); } return flow; } int main(){ //开启关闭同步且混用输入输出wa,凝视掉AC //ios_base::sync_with_stdio(false); //cin.tie(0); int T;scanf("%d",&T); while(T--){ scanf("%d%d%d",&n,&m,&l); int u,v; s=0,t=n+1+m; init(t); double w; for(int i=1;i<=n;i++){ cin>>w; addEdge(s,i,log(w)); }for(int i=1;i<=m;i++){ cin>>w; addEdge(n+i,t,log(w)); } for(int i=1;i<=l;i++){ cin>>u>>v; addEdge(u,v+n,INF); } double ans=Dinic(); printf("%.4f\n",exp(ans)); } return 0; }