标签:before mem always limit int front dde cout uil
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 20904 | Accepted: 4494 |
Description
Input
Output
Sample Input
3 4 7 2 0 4 2 6 1 2 40 3 2 70 2 3 90 1 3 120
Sample Output
110
解析 先求一遍两点之间的最短距离 然后二分答案mid,每次二分的时候构建一个网络 两点之间的距离<=mid 连一条有向边 不过要拆点 保证使它是单向的,避免不可达的可达,
跑一边最大流 如果等于牛的总数 说明mid时间内可以的到达 继续二分 出最优答案。
我为什么感觉可以费用流解决。。。有时间试一试
#include<iostream> #include<stdio.h> #include<vector> #include<string.h> #include<queue> using namespace std; typedef long long ll; const int maxn=1e3+20,mod=1e9+7; const ll inf=1e16; #define pb push_back #define mp make_pair #define X first #define Y second #define all(a) (a).begin(), (a).end() #define fillchar(a, x) memset(a, x, sizeof(a)) #define huan printf("\n"); #define debug(a,b) cout<<a<<" "<<b<<" "; ll min(ll a,ll b){return a>b?b:a;} struct edge { int from,to,c,f; edge(int u,int v,int c,int f):from(u),to(v),c(c),f(f) {} }; int n,m,N; vector<edge> edges; vector<int> g[maxn]; int d[maxn];//从起点到i的距离 int cur[maxn];//当前弧下标 ll dp[maxn][maxn]; ll a[maxn],b[maxn],sum; void init(int n) { for(int i=0; i<=N; i++) g[i].clear(); edges.clear(); } void addedge(int from,int to,int c) //加边 支持重边 { edges.push_back(edge(from,to,c,0)); edges.push_back(edge(to,from,0,0)); int siz=edges.size(); g[from].push_back(siz-2); g[to].push_back(siz-1); } int bfs(int s,int t) //构造一次层次图 { memset(d,-1,sizeof(d)); queue<int> q; q.push(s); d[s]=0; while(!q.empty()) { int x=q.front();q.pop(); for(int i=0;i<g[x].size();i++) { edge &e=edges[g[x][i]]; if(d[e.to]<0&&e.f<e.c) //d[e.to]=-1表示没访问过 { d[e.to]=d[x]+1; q.push(e.to); } } } return d[t]; } int dfs(int x,int a,int t) // a表示x点能接收的量 { if(x==t||a==0)return a; int flow=0,f;//flow总的增量 f一条增广路的增量 for(int &i=cur[x];i<g[x].size();i++)//cur[i] &引用修改其值 从上次考虑的弧 { edge &e=edges[g[x][i]]; if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.c-e.f),t))>0) //按照层次图增广 满足容量限制 { e.f+=f; edges[g[x][i]^1].f-=f; //修改流量 flow+=f; a-=f; if(a==0) break; } } return flow; } int maxflow(int s,int t) { int flow=0; while(bfs(s,t)!=-1) { memset(cur,0,sizeof(cur)); flow+=dfs(s,0x3f3f3f3f,t); } return flow; } void build(ll x) { init(N); for(int i=1;i<=n;i++) { addedge(0,i,a[i]); addedge(i+n,N,b[i]); addedge(i,i+n,0x3f3f3f3f); } for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { if(dp[i][j]<=x) { addedge(i,j+n,0x3f3f3f3f); addedge(j,i+n,0x3f3f3f3f); } } } } ll solve() { ll ans=-1; ll l=0,r=inf-1; while(l<=r) { ll mid=(l+r)/2; build(mid); int temp=maxflow(0,N); //cout<<mid<<" "<<temp<<endl; if(temp>=sum) { ans=mid; r=mid-1; } else l=mid+1; } return ans; } int main() { while(~scanf("%d%d",&n,&m)) { N=n*2+1;sum=0; for(int i=1;i<=n;i++) { scanf("%ld%ld",&a[i],&b[i]); sum+=a[i]; } //====================floyd==========================// for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) //初始化长度 { if(i==j) dp[i][j]=0; else dp[i][j]=inf; } ll x,y,d; for(int i=0;i<m;i++) { scanf("%lld%lld%lld",&x,&y,&d); if(dp[x][y]>d) dp[x][y]=dp[y][x]=d; } for(int k=1; k<=n; k++) for(int i=1; i<=n; i++) if(dp[i][k]!=inf) for(int j=1; j<=n; j++) dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]); //=========================================================// //init(n); cout<<solve()<<endl; } }
标签:before mem always limit int front dde cout uil
原文地址:https://www.cnblogs.com/stranger-/p/9368406.html