BZOJ_1877_[SDOI2009]晨跑_費用流
阿新 • • 發佈:2018-02-25
line sizeof tdi bzoj highlight string 十字路口 pat ont
BZOJ_1877_[SDOI2009]晨跑_費用流
題意:
Elaxia最近迷戀上了空手道,他為自己設定了一套健身計劃,比如俯臥撐、仰臥起坐等 等,不過到目前為止,他 堅持下來的只有晨跑。 現在給出一張學校附近的地圖,這張地圖中包含N個十字路口和M條街道,Elaxia只能從 一 個十字路口跑向另外一個十字路口,街道之間只在十字路口處相交。Elaxia每天從寢室出發 跑到學校,保證寢室 編號為1,學校編號為N。 Elaxia的晨跑計劃是按周期(包含若幹天)進行的,由於他不喜歡走重復的路線,所以 在一個周期內,每天的晨跑路線都不會相交(在十字路口處),寢室和學校不算十字路 口。Elaxia耐力不太好, 他希望在一個周期內跑的路程盡量短,但是又希望訓練周期包含的天 數盡量長。 除了練空手道,Elaxia其他時間 都花在了學習和找MM上面,所有他想請你幫忙為他設計 一套滿足他要求的晨跑計劃。 分析: 費用流。 拆個點,入點到出點連容量1的邊。 代碼:#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define N 550 #define M 180050 #define S (n+1) #define T (n) #define inf 100000000 int head[N],to[M],nxt[M],flow[M],val[M],cnt=1,n,m; int Q[N],l,r,dis[N],path[N],inq[N]; inline void add(int u,int v,int f,int w){ to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;flow[cnt]=f;val[cnt]=w; to[++cnt]=u;nxt[cnt]=head[v];head[v]=cnt;flow[cnt]=0;val[cnt]=-w; } bool spfa(){ memset(dis,0x3f,sizeof(dis));memset(path,0,sizeof(path));l=r=0; Q[r++]=S;dis[S]=0;inq[S]=1; while(l^r){ int x=Q[l++];inq[x]=0;if(l==n+n+10)l=0; for(int i=head[x];i;i=nxt[i]){ if(flow[i]>0&&dis[to[i]]>dis[x]+val[i]){ dis[to[i]]=dis[x]+val[i]; path[to[i]]=i^1; if(!inq[to[i]]){ inq[to[i]]=1;Q[r++]=to[i];if(r==n+n+10)r=0; } } } } return dis[T]<inf; } void mcmf(){ int minc=0,maxf=0; while(spfa()){ minc+=dis[T]; for(int i=T;i!=S;i=to[path[i]]){ flow[path[i]]++; flow[path[i]^1]--; } maxf++; } printf("%d %d\n",maxf,minc); } int main(){ scanf("%d%d",&n,&m); int x,y,z; for(int i=1;i<=n;i++)add(i,i+n,1,0); for(int i=1;i<=m;i++){ scanf("%d%d%d",&x,&y,&z); add(x+n,y,1,z); } mcmf(); }
BZOJ_1877_[SDOI2009]晨跑_費用流