博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ1087 ZOJ1157(最大流Isap+map映射)
阅读量:6004 次
发布时间:2019-06-20

本文共 2747 字,大约阅读时间需要 9 分钟。

题意:在一个会议室里有n种插座,每种插座一个;每个插座只能插一种以及一个电器(或者适配器);

      有m个电器,每个电器有一个插头需要插在相应一种插座上;不是所有电器都能在会议室找到相应插座;
      有k种适配器,每种适配器可以有无限多数量;每种适配器(a, b)可以把b类插座变为a类插座;
      问最后有多少个电器无法使用。

建图:

(1) 源点到每种插座连一条权值为1的边

(2) 每个电器到汇点连一条权值为1的边

(3) m个电器中,连一条对应插座到该个电器的边,权值为1

(4)k种适配器,连一条B到A的边,权值为inf

题目意思最多也就300个点,怎么开n=300,就re了,开600多,就AC了,求过路大神指点

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 using namespace std; 8 #define inf 0x7fffffff 9 #define N 666 10 #define M 350000 11 map
mp; 12 struct Edge 13 { 14 int v,w,next; 15 Edge(){} 16 Edge(int V,int W,int NEXT):v(V),w(W),next(NEXT){} 17 }edge[M]; 18 int pre[N],cur[N],dis[N],gap[N]; 19 int size,head[N]; 20 int a[105]; 21 void Init() 22 { 23 memset(head,-1,sizeof(head)); 24 size = 0; 25 } 26 void InsertEdge(int u,int v,int w)// 加边 27 { 28 edge[size] = Edge(v,w,head[u]); 29 head[u] = size++; 30 edge[size] = Edge(u,0,head[v]); 31 head[v] = size++; 32 } 33 int Isap(int st,int ed,int n) // Isap模板 34 { 35 for(int i=0; i<=n; i++) 36 { 37 gap[i] = dis[i] = 0; 38 cur[i] = head[i]; 39 } 40 int u = pre[st] = st; 41 int aug = inf ,maxflow = 0; 42 while(dis[st] < n) 43 { 44 loop: 45 for(int &i=cur[u]; i!=-1; i=edge[i].next) 46 { 47 int v = edge[i].v; 48 if(edge[i].w && dis[u]==dis[v]+1) 49 { 50 aug = min(aug,edge[i].w); 51 pre[v] = u; 52 u = v; 53 if(v==ed) 54 { 55 maxflow += aug; 56 for(u=pre[u]; v!=st; v=u,u=pre[u]) 57 { 58 edge[cur[u]].w -= aug; 59 edge[cur[u]^1].w += aug; 60 } 61 aug = inf; 62 } 63 goto loop; 64 } 65 } 66 int mindis = n; 67 for(int i=head[u]; i!=-1; i=edge[i].next) 68 { 69 int v = edge[i].v; 70 if(edge[i].w && dis[v] < mindis) 71 { 72 cur[u] = i; 73 mindis = dis[v]; 74 } 75 } 76 if(--gap[dis[u]]==0) break; 77 gap[dis[u]=mindis+1]++; 78 u = pre[u]; 79 } 80 return maxflow; 81 } 82 83 int main() 84 { 85 int T,n,m,k,st,ed,nv; 86 string s1,s2; 87 Init(); 88 mp.clear(); 89 scanf("%d",&n); 90 st = 0 ; nv = 1; //源点st为0,nv初始化为1,方便源点从0开始 91 for(int i=0; i
>s1; 94 if(mp.find(s1)==mp.end()) mp[s1] = nv++; //map映射 95 InsertEdge(st,mp[s1],1); //源点到每种插座连一条权值为1的边 96 } 97 scanf("%d",&m); 98 int cnt=0; 99 for(int i=0; i
>s1>>s2;102 if(mp.find(s1)==mp.end()) mp[s1] = nv++; //map映射 103 if(mp.find(s2)==mp.end()) mp[s2] = nv++; //map映射 104 InsertEdge(mp[s2],mp[s1],1); //m个电器中,连一条对应插座到该个电器的边,权值为1105 a[cnt++] = mp[s1]; //数组a记录设备的结点号 106 }107 scanf("%d",&k);108 for(int i=0; i
>s1>>s2;111 if(mp.find(s1)==mp.end()) mp[s1] = nv++; //map映射 112 if(mp.find(s2)==mp.end()) mp[s2] = nv++; //map映射 113 InsertEdge(mp[s2],mp[s1],inf); //k种适配器,连一条B到A的边,权值为inf114 }115 ed = nv;// 汇点 116 for(int i=0; i
View Code

 

 

 

转载于:https://www.cnblogs.com/ar940507/p/3265554.html

你可能感兴趣的文章
KJMusic完整音乐项目
查看>>
lamp (module) 部署应用
查看>>
Linux的文件找工具find的小秘密
查看>>
bash基础命令参考
查看>>
linux的多种安装方式及安装注意事项
查看>>
linux分区命名及安装注意
查看>>
Nginx部署文档(二进制包安装)
查看>>
基于ubuntu的mrtg配置,实现监控多台服务器系统资源
查看>>
Spring配置文件配置bean
查看>>
tomcat下安装jdk
查看>>
怎么关闭或禁用联想ThinkPad笔记本的触摸板
查看>>
linux系统目录分支结构及存放内容
查看>>
毕业设计笔记
查看>>
XMLHttpRequest 及其open()的用法
查看>>
进程与线程的定义以及对多线程、多进程、并发和并行的理解
查看>>
nginx默认虚拟主机、用户认证、域名重定向
查看>>
华为命令二部分
查看>>
2018-03-20
查看>>
LINUX系统重新安装,保留data,以及使用LVM管理
查看>>
袋鼠云数据中台专栏2.0 | 企业三界:业务界面,应用界面,数据界面
查看>>