网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流……于是乎来一发题解。
1. COGS2093 花园的守护之神
题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长。
用Dijkstra或者SPFA跑出来s-t最短路,然后把最短路DAG上的每条边的容量设为1,跑最小割即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define INF ((~((1)<<(31)))>>(1))
using namespace std;
const int maxn=,maxe=;
struct edge1{int from,to,prev;long long dis;}e1[maxe<<];
struct edge2{int to,cap,prev;}e2[maxe<<];
struct node{
int x;
long long dis;
node(int x,long long dis):x(x),dis(dis){}
bool operator<(const node &a)const{return dis>a.dis;}
};
void addedge1(int,int,long long);
void addedge2(int,int,int);
void Dijkstra(int,long long*);
int Dinic();
void bfs();
int dfs(int,int);
int n,m,s,t,last1[maxn]={},len1=,last2[maxn],len2=,now[maxn],d[maxn],q[maxn],head,tail,x,y;
long long dis[maxn],redis[maxn],z;
bool vis[maxn];
int main(){
#define MINE
#ifdef MINE
freopen("greendam2002.in","r",stdin);
freopen("greendam2002.out","w",stdout);
#endif
memset(last2,-,sizeof(last2));
scanf("%d%d%d%d",&n,&m,&s,&t);
for(int i=;i<=m;i++){
scanf("%d%d%lld",&x,&y,&z);
addedge1(x,y,z);
addedge1(y,x,z);
}
Dijkstra(s,dis);
Dijkstra(t,redis);
for(int i=;i<=(m<<);i++)if(dis[e1[i].from]+e1[i].dis+redis[e1[i].to]==dis[t]){
addedge2(e1[i].from,e1[i].to,);
addedge2(e1[i].to,e1[i].from,);
}
printf("%d",Dinic());
#ifndef MINE
printf("\n--------------------DONE--------------------\n");
for(;;);
#endif
return ;
}
void addedge1(int x,int y,long long z){
e1[++len1].from=x;
e1[len1].to=y;
e1[len1].dis=z;
e1[len1].prev=last1[x];
last1[x]=len1;
}
void addedge2(int x,int y,int z){
e2[len2].to=y;
e2[len2].cap=z;
e2[len2].prev=last2[x];
last2[x]=len2++;
}
void Dijkstra(int x,long long *dis){
memset(vis,,sizeof(vis));
priority_queue<node>q;
memset(dis,,sizeof(long long)*maxn);
dis[x]=;
q.push(node(x,));
while(!q.empty()){
x=q.top().x;
q.pop();
if(vis[x])continue;
vis[x]=true;
for(int i=last1[x];i;i=e1[i].prev)if(dis[e1[i].to]>dis[x]+e1[i].dis){
dis[e1[i].to]=dis[x]+e1[i].dis;
q.push(node(e1[i].to,dis[e1[i].to]));
}
}
}
int Dinic(){
int ans=;
for(;;){
bfs();
if(d[t]==INF)break;
memset(now,,sizeof(now));
ans+=dfs(s,INF);
}
return ans;
}
void bfs(){
int x;
fill_n(d+,n,INF);
d[s]=;
head=tail=;
q[tail++]=s;
while(head!=tail){
x=q[head++];
for(int i=last2[x];i!=-;i=e2[i].prev)if(e2[i].cap>&&d[e2[i].to]==INF){
d[e2[i].to]=d[x]+;
q[tail++]=e2[i].to;
}
}
}
int dfs(int x,int delta){
if(x==t||!delta)return delta;
int flow=,f;
for(int i=(now[x]?e2[now[x]].prev:last2[x]);i!=-;i=e2[i].prev)if(e2[i].cap>&&d[e2[i].to]==d[x]+){
now[x]=i;
f=dfs(e2[i].to,min(delta,e2[i].cap));
if(!f)continue;
e2[i].cap-=f;
e2[i^].cap+=f;
flow+=f;
delta-=f;
if(!delta)break;
}
return flow;
}
2. [NEERC 2003][POJ2125]有向图破坏
题意:给定一个有向图,可以删除一个点所有的出边,费用为wi;或者删除一个点所有的入边,费用为wi’,求把所有边都删掉所需的最少费用。
把点拆成出点和入点,有向边变成连接出点和入点的边,然后就是二分图最小权点覆盖问题。
其实这不是费用流,直接把s到出点和入点到t的边的容量设为对应的费用,其他边容量正无穷,再跑最大流就行。至于为什么,因为这是最小割,不是最小费用最大流。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define INF (0x3f3f3f3f)
using namespace std;
const int maxn=<<,maxe=;
struct edge{int to,cap,cost,prev;}e[maxe];
void addedge(int,int,int);
void insert(int,int,int);
int Dinic();
void bfs();
int dfs(int,int);
int n,m,s,t,last[maxn],len=,d[maxn],now[maxn],q[maxn],head,tail,tmp,x,y;
int main(){
#define MINE
#ifdef MINE
freopen("destroyingthegraph.in","r",stdin);
freopen("destroyingthegraph.out","w",stdout);
#endif
memset(last,-,sizeof(last));
scanf("%d%d",&n,&m);
s=(n<<)+;
t=s+;
for(int i=;i<=n;i++){
scanf("%d",&tmp);
addedge(i+n,t,tmp);
}
for(int i=;i<=n;i++){
scanf("%d",&tmp);
addedge(s,i,tmp);
}
while(m--){
scanf("%d%d",&x,&y);
addedge(x,y+n,INF);
}
printf("%d",Dinic());
#ifndef MINE
printf("\n-------------------------DONE-------------------------\n");
for(;;);
#endif
return ;
}
void addedge(int x,int y,int z){
insert(x,y,z);
insert(y,x,);
}
void insert(int x,int y,int z){
e[len].to=y;
e[len].cap=z;
e[len].prev=last[x];
last[x]=len++;
}
int Dinic(){
int ans=;
for(;;){
bfs();
if(d[t]==INF)break;
memset(now,,sizeof(now));
ans+=dfs(s,INF);
}
return ans;
}
void bfs(){
int x;
memset(d,,sizeof(d));
d[s]=;
head=tail=;
q[tail++]=s;
while(head!=tail){
x=q[head++];
for(int i=last[x];i!=-;i=e[i].prev)if(e[i].cap>&&d[e[i].to]>d[x]+){
d[e[i].to]=d[x]+;
q[tail++]=e[i].to;
}
}
}
int dfs(int x,int delta){
if(x==t||!delta)return delta;
int flow=,f;
for(int i=(now[x]?e[now[x]].prev:last[x]);i!=-;i=e[i].prev)if(e[i].cap>&&d[e[i].to]==d[x]+){
now[x]=i;
f=dfs(e[i].to,min(delta,e[i].cap));
if(!f)continue;
e[i].cap-=f;
e[i^].cap+=f;
flow+=f;
delta-=f;
if(!delta)break;
}
return flow;
}
3. [SGU252]铁路网
题意略,总之就是带边权的最小路径覆盖问题。
拆二分图,连带费用的边,然后一发最小费用最大流就行。必须最大流的原因在于这是最少路径条数覆盖,所以必须增广到最大流才能保证所求出的是最小路径覆盖。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=,maxe=;
struct edge{int to,cap,cost,prev;}e[maxe<<];
void addedge(int,int,int,int);
void insert(int,int,int,int);
void mincostmaxflow();
void SPFA();
int n,m,last[maxn],len=,dis[maxn],p[maxn],s,t,flow=,cost=,x,y,z;
bool inq[maxn];
int main(){
#define MINE
#ifdef MINE
freopen("railwaycommunication.in","r",stdin);
freopen("railwaycommunication.out","w",stdout);
#endif
memset(last,-,sizeof(last));
scanf("%d%d",&n,&m);
s=(n<<|);
t=s+;
for(int i=;i<=n;i++){
addedge(s,i,,);
addedge(i+n,t,,);
}
while(m--){
scanf("%d%d%d",&x,&y,&z);
addedge(x,y+n,,z);
}
mincostmaxflow();
printf("%d %d",n-flow,cost);
#ifndef MINE
printf("\n-------------------------DONE-------------------------\n");
for(;;);
#endif
return ;
}
void addedge(int x,int y,int z,int w){
insert(x,y,z,w);
insert(y,x,,-w);
}
void insert(int x,int y,int z,int w){
e[len].to=y;
e[len].cap=z;
e[len].cost=w;
e[len].prev=last[x];
last[x]=len++;
}
void mincostmaxflow(){
int delta,x;
for(;;){
SPFA();
if(dis[t]==0x3f3f3f3f)break;
delta=~(<<);
for(x=t;x!=s;x=e[p[x]^].to)delta=min(delta,e[p[x]].cap);
for(x=t;x!=s;x=e[p[x]^].to){
e[p[x]].cap-=delta;
e[p[x]^].cap+=delta;
cost+=e[p[x]].cost*delta;
}
flow+=delta;
}
}
void SPFA(){
int x;
memset(dis,,sizeof(dis));
memset(inq,,sizeof(inq));
queue<int>q;
q.push(s);
dis[s]=;
while(!q.empty()){
x=q.front();
q.pop();
inq[x]=false;
for(int i=last[x];i!=-;i=e[i].prev)if(e[i].cap>&&dis[e[i].to]>dis[x]+e[i].cost){
dis[e[i].to]=dis[x]+e[i].cost;
p[e[i].to]=i;
if(!inq[e[i].to]){
inq[e[i].to]=true;
q.push(e[i].to);
}
}
}
}
4. [ZJOI2010]网络扩容
题意:给定一张有向图,每条边都有一个容量C和一个将容量扩大1所需的费用W。求在不扩容的情况下,1到N的最大流和将1到N的最大流增加K所需的最小扩容费用。
每条边拆成两条边,一条容量为C费用为0,一条容量正无穷费用为W,然后跑费用为0时的最大流,再在残量网络上跑固定流量最小费用流即可。
一开始的最大流可以用Dinic之类的算法写,(懒得再写一份最大流的)也可以用费用流代替,只要在费用增大到大于0之前记录流量即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<deque>
using namespace std;
const int maxn=,maxe=;
struct edge{int to,cap,cost,prev;}e[maxn<<];
void addedge(int,int,int,int);
void insert(int,int,int,int);
int Dinic();
void bfs();
int dfs(int,int);
int mincostflow();
void SPFA();
int n,m,k,last[maxn],len=,s,t,dis[maxn],now[maxn],q[maxn],head,tail,p[maxn],x,y,z,w;
bool inq[maxn];
int main(){
#define MINE
#ifdef MINE
freopen("networkzj2010.in","r",stdin);
freopen("networkzj2010.out","w",stdout);
#endif
memset(last,-,sizeof(last));
scanf("%d%d%d",&n,&m,&k);
s=;
t=n;
while(m--){
scanf("%d%d%d%d",&x,&y,&z,&w);
addedge(x,y,z,);
addedge(x,y,0x3f3f3f3f,w);
}
printf("%d ",Dinic());
printf("%d",mincostflow());
#ifndef MINE
printf("\n-------------------------DONE-------------------------\n");
for(;;);
#endif
return ;
}
void addedge(int x,int y,int z,int w){
insert(x,y,z,w);
insert(y,x,,-w);
}
void insert(int x,int y,int z,int w){
e[len].to=y;
e[len].cap=z;
e[len].cost=w;
e[len].prev=last[x];
last[x]=len++;
}
int Dinic(){
int ans=;
for(;;){
bfs();
if(dis[t]==0x3f3f3f3f)break;
memset(now,,sizeof(now));
ans+=dfs(s,~(<<));
}
return ans;
}
void bfs(){
int x;
memset(dis,,sizeof(dis));
dis[s]=;
head=tail=;
q[tail++]=s;
while(head!=tail){
x=q[head++];
for(int i=last[x];i!=-;i=e[i].prev)if(!e[i].cost&&e[i].cap>&&dis[e[i].to]>dis[x]+){
dis[e[i].to]=dis[x]+;
q[tail++]=e[i].to;
}
}
}
int dfs(int x,int delta){
if(x==t||!delta)return delta;
int flow=,f;
for(int i=(now[x]?e[now[x]].prev:last[x]);i!=-;i=e[i].prev)if(!e[i].cost&&e[i].cap>&&dis[e[i].to]==dis[x]+){
now[x]=i;
f=dfs(e[i].to,min(delta,e[i].cap));
if(!f)continue;
e[i].cap-=f;
e[i^].cap+=f;
flow+=f;
delta-=f;
if(!delta)break;
}
return flow;
}
int mincostflow(){
int ans=,x,delta;
for(;;){
SPFA();
if(dis[t]==0x3f3f3f3f)break;
delta=k;
for(x=t;x!=s;x=e[p[x]^].to)delta=min(delta,e[p[x]].cap);
for(x=t;x!=s;x=e[p[x]^].to){
e[p[x]].cap-=delta;
e[p[x]^].cap+=delta;
ans+=e[p[x]].cost*delta;
}
k-=delta;
if(!k)break;
}
return ans;
}
void SPFA(){
int x;
memset(dis,,sizeof(dis));
memset(inq,,sizeof(inq));
deque<int>q;
q.push_back(s);
dis[s]=;
while(!q.empty()){
x=q.front();
q.pop_front();
inq[x]=false;
for(int i=last[x];i!=-;i=e[i].prev)if(e[i].cap>&&dis[e[i].to]>dis[x]+e[i].cost){
dis[e[i].to]=dis[x]+e[i].cost;
p[e[i].to]=i;
if(!inq[e[i].to]){
inq[e[i].to]=true;
if(!q.empty()&&dis[e[i].to]<dis[q.front()])q.push_front(e[i].to);
else q.push_back(e[i].to);
}
}
}
}
5. 最小最大生成树
题意:给定一个带权无向连通图,求使得加入的权值为w的边(u,v)既能出现在最小生成树上也能出现在最大生成树上所需要删除的最少边数。
一条权为w的边(u,v)不能出现在最小生成树上的充要条件是u,v可以只借助边权<w的边而连通,所以直接把边权<w的所有边扔进图里,容量为1,然后跑u-v最小割即可。最大生成树同理。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF (0x3f3f3f3f)
using namespace std;
const int maxn=,maxe=;
struct edge1{int from,to,w;}ee[maxe];
struct edge{int to,cap,prev;}e[maxe<<];
void addedge(int,int,int);
int Dinic();
void bfs();
int dfs(int,int);
int n,m,last[maxn],len=,d[maxn],now[maxn],q[maxn],head,tail,s,t,w,ans=;
int main(){
#define MINE
#ifdef MINE
freopen("mstmn.in","r",stdin);
freopen("mstmn.out","w",stdout);
#endif
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)scanf("%d%d%d",&ee[i].from,&ee[i].to,&ee[i].w);
scanf("%d%d%d",&s,&t,&w);
memset(last,-,sizeof(last));
for(int i=;i<=m;i++)if(ee[i].w<w){
addedge(ee[i].from,ee[i].to,);
addedge(ee[i].to,ee[i].from,);
}
ans+=Dinic();
memset(last,-,sizeof(last));
len=;
for(int i=;i<=m;i++)if(ee[i].w>w){
addedge(ee[i].from,ee[i].to,);
addedge(ee[i].to,ee[i].from,);
}
ans+=Dinic();
printf("%d",ans);
#ifndef MINE
printf("\n-------------------------DONE-------------------------\n");
for(;;);
#endif
return ;
}
void addedge(int x,int y,int z){
e[len].to=y;
e[len].cap=z;
e[len].prev=last[x];
last[x]=len++;
}
int Dinic(){
int ans=;
for(;;){
bfs();
if(d[t]==INF)break;
memset(now,,sizeof(now));
ans+=dfs(s,INF);
}
return ans;
}
void bfs(){
int x;
memset(d,,sizeof(d));
head=tail=;
q[tail++]=s;
d[s]=;
while(head!=tail){
x=q[head++];
for(int i=last[x];i!=-;i=e[i].prev)if(e[i].cap>&&d[e[i].to]>d[x]+){
d[e[i].to]=d[x]+;
q[tail++]=e[i].to;
}
}
}
int dfs(int x,int delta){
if(x==t||!delta)return delta;
int flow=,f;
for(int i=(now[x]?e[now[x]].prev:last[x]);i!=-;i=e[i].prev)if(e[i].cap>&&d[e[i].to]==d[x]+){
now[x]=i;
f=dfs(e[i].to,min(delta,e[i].cap));
if(!f)continue;
e[i].cap-=f;
e[i^].cap+=f;
flow+=f;
delta-=f;
if(!delta)break;
}
return flow;
}
6. [网络流24题]餐巾
题意略。
把每天拆成早上和晚上两个点,再新增一个源点s(可以理解为卖餐巾的地方……),从s到每个早上连一条费用为买餐巾费用,容量正无穷的边,从每天早上到晚上连一条流量下界为所需餐巾数的边,从每天晚上向往后a天的早上连费用为快洗费用,流量正无穷的边,慢洗同理。再从每天晚上到后一天晚上连一条费用为0容量正无穷的边,表示餐巾没用上留到明天晚上。这样建图之后可以把每个流量理解为一条餐巾(到处流的餐巾……),那么要求的就是满足那些下界的最小费用可行流。
带下界这个问题也很好说,把它的费用改成负无穷,容量为它的下界,那么跑最小费用流增广的时候一定会增广完它之后才会停止,所以这样转换之后可以保证所有下限都能够被满足。最后把费用减去这一堆负无穷即可。
其实三分贪心比起费用流来说又好写又快……
这份代码是我费用流没学好的时候写的,用的是dfs增广……Too young too simple……
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define LL long long
#define INF ((~(1<<31))>>1)
using namespace std;
const int maxn=<<;
struct edge{int to,cap,prev;LL cost;}e[];
void addedge(int,int,int,LL);
void insert(int,int,int,LL);
void mincostflow();
void SPFA();
int dfs(int,int);
int last[maxn],len=,now[maxn];
bool inq[maxn];
int n,a,b,s,t;
LL ca,cb,cc,c[maxn],dis[maxn],ans=0ll;
int main(){
freopen("napkin.in","r",stdin);
freopen("napkin.out","w",stdout);
memset(last,-,sizeof(last));
scanf("%d",&n);
a++;b++;
s=(n<<|);t=s+;
for(int i=;i<=n;i++)scanf("%lld",&c[i]);
scanf("%lld%d%lld%d%lld",&cc,&a,&ca,&b,&cb);
for(int i=;i<=n;i++){
ans+=c[i]*INF;
addedge(s,i,INF,cc);
addedge(i,i+n,c[i],-INF);
if(i<n)addedge(i+n,i+n+,INF,);
if(i+a<=n)addedge(i+n,i+a,INF,ca);
if(i+b<=n)addedge(i+n,i+b,INF,cb);
}
t=n+n;
mincostflow();
printf("%lld",ans);
fclose(stdin);
fclose(stdout);
return ;
}
void addedge(int x,int y,int z,LL w){
//printf("addedge(%d,%d,%d,%lld)\n",x,y,z,w);
insert(x,y,z,w);
insert(y,x,,-w);
}
void insert(int x,int y,int z,LL w){
e[len].to=y;
e[len].cap=z;
e[len].cost=w;
e[len].prev=last[x];
last[x]=len++;
}
void mincostflow(){
for(;;){
SPFA();
if(dis[t]>=0ll)break;
memset(now,,sizeof(now));
dfs(s,INF);
}
}
void SPFA(){
int x;
memset(inq,,sizeof(inq));
memset(dis,,sizeof(dis));
queue<int>q;
q.push(s);
dis[s]=;
while(!q.empty()){
x=q.front();
q.pop();
inq[x]=false;
for(int i=last[x];i!=-;i=e[i].prev)if(e[i].cap>&&dis[e[i].to]>dis[x]+e[i].cost){
dis[e[i].to]=dis[x]+e[i].cost;
if(!inq[e[i].to]){
inq[e[i].to]=true;
q.push(e[i].to);
}
}
}
}
int dfs(int x,int delta){
if(x==t||!delta)return delta;
int f;
for(int i=(now[x]?e[now[x]].prev:last[x]);i!=-;i=e[i].prev)if(e[i].cap>&&dis[e[i].to]==dis[x]+e[i].cost){
now[x]=i;
f=dfs(e[i].to,min(delta,e[i].cap));
if(!f)continue;
e[i].cap-=f;
e[i^].cap+=f;
ans+=e[i].cost*(LL)f;
return f;
}
return ;
}
7. COGS1632 搬运工
题意略,带权二分图点覆盖。
为了保证次数最小,把边权统一加上100000,然后跑最大流即可。最后的最小次数是流量/100000,最少费用是流量%100000。
不得不说这个建图比较机智……其实也是用大的屏蔽小的来实现优先级之类的玩意儿。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=;
struct edge{int to,prev,cap;}e[maxn*maxn<<];
void addedge(int,int,int);
void AddEdge(int,int,int);
int Dinic();
void bfs(int);
int dfs(int,int);
int last[maxn],d[maxn],now[maxn],q[maxn];
int n,len=,head,tail,s,t,tmp;
char c;
inline int MAIN(){
#define MINE
#ifdef MINE
freopen("worker.in","r",stdin);
freopen("worker.out","w",stdout);
#endif
memset(last,-,sizeof(last));
scanf("%d",&n);
for(int i=;i<=n;i++)for(int j=;j<=n;j++){
scanf(" %c",&c);
if(c=='*')addedge(i,j+n,(~(<<))>>);
}
s=n<<|;t=s+;
for(int i=;i<=n;i++){
scanf("%d",&tmp);
addedge(s,i,tmp+);
}
for(int i=;i<=n;i++){
scanf("%d",&tmp);
addedge(i+n,t,tmp+);
}
n=(n<<)+;
tmp=Dinic();
printf("%d %d",tmp/,tmp%);
#ifndef MINE
printf("\n-------------------------DONE-------------------------\n");
for(;;);
#endif
return ;
}
int hzoier=MAIN();
int main(){;}
void addedge(int x,int y,int z){
AddEdge(x,y,z);
AddEdge(y,x,);
}
void AddEdge(int x,int y,int z){
e[len].to=y;
e[len].cap=z;
e[len].prev=last[x];
last[x]=len++;
}
int Dinic(){
int ans=;
for(;;){
bfs(s);
if(d[t]>n)break;
memset(now,,sizeof(now));
ans+=dfs(s,~(<<));
}
return ans;
}
void bfs(int x){
memset(d,,sizeof(d));
d[x]=;
head=tail=;
q[tail++]=x;
while(head!=tail){
x=q[head++];
for(int i=last[x];i!=-;i=e[i].prev)if(e[i].cap>&&d[e[i].to]>n){
d[e[i].to]=d[x]+;
q[tail++]=e[i].to;
}
}
}
int dfs(int x,int delta){
if(x==t||!delta)return delta;
int flow=,f;
for(int i=now[x]?e[now[x]].prev:last[x];i!=-;i=e[i].prev)if(e[i].cap>&&d[e[i].to]==d[x]+){
now[x]=i;
f=dfs(e[i].to,min(delta,e[i].cap));
if(!f)continue;
e[i].cap-=f;
e[i^].cap+=f;
flow+=f;
delta-=f;
if(!delta)break;
}
return flow;
}
网络流n题 题解的更多相关文章
- 【题解】【网络流24题】航空路线问题 [P2770] [Loj6122]
[题解][网络流24题]航空路线问题 [P2770] [Loj6122] 传送门:航空路线问题 \([P2770]\) \([Loj6122]\) [题目描述] 给出一张有向图,每个点(除了起点 \( ...
- 【题解】【网络流24题】汽车加油行驶问题 [P4009] [Loj6223]
[题解][网络流24题]汽车加油行驶问题 [P4009] [Loj6223] 传送门:汽车加油行驶问题 \([P4009]\) \([Loj6223]\) [题目描述] 给出一个 \(N \times ...
- [网络流24题]最长k可重区间集[题解]
最长 \(k\) 可重区间集 题目大意 给定实心直线 \(L\) 上 \(n\) 个开区间组成的集合 \(I\) ,和一个正整数 \(k\) ,试设计一个算法,从开区间集合 \(I\) 中选取开区间集 ...
- 【线性规划与网络流 24题】已完成(3道题因为某些奇怪的原因被抛弃了QAQ)
写在前面:SDOI2016 Round1滚粗后蒟蒻开始做网络流来自我拯救(2016-04-11再过几天就要考先修课,现在做网络流24题貌似没什么用←退役节奏) 做的题目将附上日期,见证我龟速刷题. 1 ...
- LOJ6000 - 「网络流 24 题」搭配飞行员
原题链接 题意简述 求二分图的最大匹配. 题解 这里写的是匈牙利算法. 表示节点的当前匹配. 为真表示在这一轮匹配中,无法给节点一个新的匹配.所以如果为真就不用再dfs它了,直接continue就好. ...
- 【网络流24题】最长k可重线段集(费用流)
[网络流24题]最长k可重线段集(费用流) 题面 Cogs的数据有问题 Loj 洛谷 题解 这道题和最长k可重区间集没有区别 只不过费用额外计算一下 但是,还是有一点要注意的地方 这里可以是一条垂直的 ...
- 【网络流24题】最长k可重区间集(费用流)
[网络流24题]最长k可重区间集(费用流) 题面 Cogs Loj 洛谷 题解 首先注意一下 这道题目里面 在Cogs上直接做就行了 洛谷和Loj上需要判断数据合法,如果\(l>r\)就要交换\ ...
- 【刷题】LOJ 6227 「网络流 24 题」最长k可重线段集问题
题目描述 给定平面 \(\text{xoy}\) 上 \(n\) 个开线段组成的集合 \(\text{I}\) ,和一个正整数 \(k\) ,试设计一个算法. 从开线段集合 \(\text{I}\) ...
- 【刷题】LOJ 6121 「网络流 24 题」孤岛营救问题
题目描述 1944 年,特种兵麦克接到国防部的命令,要求立即赶赴太平洋上的一个孤岛,营救被敌军俘虏的大兵瑞恩.瑞恩被关押在一个迷宫里,迷宫地形复杂,但幸好麦克得到了迷宫的地形图.迷宫的外形是一个长方形 ...
随机推荐
- 10个CSS简写及优化技巧
CSS简写就是指将多行的CSS属性简写成一行,又称为CSS代码优化或CSS缩写.CSS简写的最大好处就是能够显著减少CSS文件的大小,优化网站整体性能,更加容易阅读. 下面介绍常见的CSS简写规则: ...
- onselectstart与onselect
这两个事件看起来很相似,事实上却非常的不同. onselectstart onselectstart几乎可以用于所有对象,其触发时间为目标对象被开始选中时(即选中动作刚开始,尚未实质性被选中).该事件 ...
- Codeforces Round #380(div 2)
A. 题意:给你一串字符串(<=100),将ogo ogogo ogogogo ogogogogo……这种全部缩成***,输出缩后的字符串 分析:第一遍扫对于那些go的位置,记录下next[i] ...
- ansible的SSH连接问题
问题描述: 在ansible安装完毕后一般需要以SSH的方式连接到需要进行管理的目标主机,一开始遇到了如下问题: # ansible -m ping all 10.200.xx.xx | UNREAC ...
- 在渲染前获取 View 的宽高
在渲染前获取 View 的宽高 这是一个比较有意义的问题,或者说有难度的问题,问题的背景为:有时候我们需要在view渲染前去获取其宽高,典型的情形是,我们想在onCreate.onStart.onRe ...
- sphinx应用
sphinx调用原理 只需要提交要查询,sphinx将返回唯一的id号 API调用 1.创建连接 $sphinx = new SphinxClient(); $sphinx->SetServ ...
- 没有为 COM 互操作注册程序集 请使用 regasm.exe /tlb 注册该程序集——解决办法
错误现象: 错误 6 没有为 COM 互操作注册程序集“DevExpress.Utils.v13.1, Version=13.1.7.0, Culture=neutral, PublicKeyToke ...
- Introduction to Neural Machine Translation - part 1
The Noise Channel Model \(p(e)\): the language Model \(p(f|e)\): the translation model where, \(e\): ...
- WebService学习总结(四)——调用第三方提供的webService服务
http://www.cnblogs.com/xdp-gacl/p/4260627.html 互联网上面有很多的免费webService服务,我们可以调用这些免费的WebService服务,将一些其他 ...
- Gravatar注册
今天在学习falsk时需要用到头像扩展,需要使用gravatar到网上查了查好像没有被墙,就试着用qq邮箱注册了一个账号,结果等了好长时间也没有等到激活邮箱,就百度了一下发现了一个技巧,原来这封邮件被 ...