https://www.luogu.org/problemnew/show/P2055

这是一个错误的示范。

一开始觉得就找一条路从外校同学连到本校同学然后最终从周末回家的同学流出,每个人睡后一个人的床就可以了。

首先我没有考虑人不能分身,导致可能会有两条路经过同一个同学。

然后我把这个同学拆点限制流量,然后样例都过不了还调半天。

#include<bits/stdc++.h>
using namespace std; const int MAXN=;
const int MAXM=;
const int INF=0x3f3f3f3f;
struct Edge{
int to,next,cap,flow,cost;
}edge[MAXM];
int head[MAXN],tol;
int pre[MAXN],dis[MAXN];
bool vis[MAXN]; int N;
void init(){
tol=;
memset(head,-,sizeof(head));
} void addedge(int u,int v,int cap,int cost){
edge[tol].to=v;
edge[tol].cap=cap;
edge[tol].cost=cost;
edge[tol].flow=;
edge[tol].next=head[u];
head[u]=tol++; edge[tol].to=u;
edge[tol].cap=;
edge[tol].cost=-cost;
edge[tol].flow=;
edge[tol].next=head[v];
head[v]=tol++;
} bool spfa(int s,int t){
queue<int> q;
memset(dis,INF,sizeof(dis));
memset(vis,false,sizeof(vis));
memset(pre,-,sizeof(pre)); dis[s]=;
vis[s]=true;
q.push(s);
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=false;
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].to;
if(edge[i].cap>edge[i].flow&&dis[v]>dis[u]+edge[i].cost){
dis[v]=dis[u]+edge[i].cost;
pre[v]=i;
if(!vis[v]){
vis[v]=true;
q.push(v);
}
}
}
}
if(pre[t]==-)
return false;
else
return true;
} int minCostMaxFlow(int s,int t,int &cost){
int flow=;
cost=;
while(spfa(s,t)){
int Min=INF;
for(int i=pre[t];i!=-;i=pre[edge[i^].to]){
if(Min>edge[i].cap-edge[i].flow)
Min=edge[i].cap-edge[i].flow;
}
for(int i=pre[t];i!=-;i=pre[edge[i^].to]){
edge[i].flow+=Min;
edge[i^].flow-=Min;
cost+=edge[i].cost*Min;
}
flow+=Min;
}
return flow;
}
/*
int main(){
int M,S,T;
scanf("%d%d%d%d",&N,&M,&S,&T);
init();
while(M--){
int u,v,cap,cost;
scanf("%d%d%d%d",&u,&v,&cap,&cost);
addedge(u,v,cap,cost);
}
int cost=0;
int flow=minCostMaxFlow(S,T,cost); printf("%d %d\n",flow,cost);
}
*/
int inschool[]; int in(int id){
return id;
} int out(int id){
return id+N;
} int main() {
int T;
scanf("%d",&T);
while(T--){
init(); scanf("%d",&N);
int n=N,s=,t=*N+;
int cntfroms=; /*这样建图错在每个人不能分身,认识他的人不能经过他去睡别人的床*/
/*for(int i=1;i<=n;i++){
scanf("%d",&inschool[i]);
if(inschool[i]==0){
addedge(s,i,1,1);
cntfroms++;
}
}
for(int i=1;i<=n;i++){
int tt;
scanf("%d",&tt);
if(inschool[i]==1&&tt==1){
addedge(i,t,1,1);
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
int tmp;
scanf("%d",&tmp);
if(tmp){
addedge(i,j,1,1);
}
}
}*/ /*把一个人拆点限制点流量*/
for(int i=;i<=n;i++){
scanf("%d",&inschool[i]);
if(inschool[i]==){
//他不是在校生,从校外源点进来
addedge(s,in(i),,);
cntfroms++;
}
else{
//他是在校生
;
} }
for(int i=;i<=n;i++){
int tt;
scanf("%d",&tt);
if(inschool[i]==){
if(tt==){
//他是在校生,并且他周末回家
addedge(out(i),t,,);
}
else{
//他不回家
;
}
}
else{
//他不是在校生
;
}
}
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
int tmp;
scanf("%d",&tmp);
if(tmp){
addedge(in(i),out(j),,);
addedge(out(i),in(j),,);
}
//cout<<"!";
} addedge(in(i),out(i),,);
} int cost=;
int maxflow=minCostMaxFlow(s,t,cost); //cout<<cost<<endl;
if(maxflow==cntfroms){
printf("^_^\n");
}
else{
printf("T_T\n");
//cout<<maxflow<<endl;
}
}
return ;
}

最新文章

  1. 第14章 Linux启动管理(3)_系统修复模式
  2. NGINX实现反向代理
  3. 浅谈Json和jsonp
  4. Leetcode 详解(ReverseWords)
  5. python新技能get——看!源!码!
  6. WPF入口Application
  7. 500Internal Server Error
  8. Nexus手动更新索引
  9. php 判断字符串在另一个字符串中位置
  10. hdu4631Sad Love Story(多校3)(最接近点对)
  11. 利用jks2pfx转换keystore格式的证书为pfs格式(含秘钥和证书的形式)
  12. c#求slope线性回归斜率
  13. CentOS 6 用SVN自动提交文件到web服务器
  14. maven使用.02.一些概念
  15. JAVA-反射学习
  16. React Redux学习笔记
  17. WPF界面XAML中的if……else……
  18. jenkins修改数据存放路径
  19. 微信小程序(六) 文章详情静态页面detail
  20. rpgmakermv \c 常用颜色一览

热门文章

  1. tcp三次握手和syn 洪水攻击
  2. Unity3d中制作异步Loading进度条所遇到的问题
  3. Method Swizzling以及AOP编程:在运行时进行代码注入-b
  4. vs2010配置VL_FEAT库
  5. VirtualBox 虚拟Ubuntu系统与主机互ping
  6. 【日常学习】【二叉树遍历】Uva548 - Tree题解
  7. ViewPagerTransforms
  8. DTD笔记
  9. java设计模式----迭代器模式和组合模式
  10. u-boot简单学习笔记(一)