poj 2455

题意:由一个点走到另一个点,中间的点可以重复到达,但边只能经过一次,问T条边不重复的路径里,最长的边的最小值.

分析:由于点是可以重用的,因此不必拆点.这道题有重边,而且重边都必须保留,因为点是可以重复走的.二分最长的边长,用最大流来验证.

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 const int MAXN=205;//点数的最大值
  5 const int MAXM=160005;//边数的最大值
  6 const int INF=0x3fffffff;
  7 
  8 struct Node
  9 {
 10     int from,to,next;
 11     int cap;
 12 }edge[MAXM];
 13 
 14 int tol;
 15 int head[MAXN];
 16 int dep[MAXN];
 17 int gap[MAXN];//gap[x]=y :说明残留网络中dep[i]==x的个数为y
 18 int n;//n是总的点的个数,包括源点和汇点
 19 Node container[40005];
 20 
 21 void init()
 22 {
 23     tol=0;
 24     memset(head,-1,sizeof(head));
 25 }
 26 
 27 void addedge(int u,int v,int w)
 28 {
 29     edge[tol].from=u;
 30     edge[tol].to=v;
 31     edge[tol].cap=w;
 32     edge[tol].next=head[u];
 33     head[u]=tol++;
 34     edge[tol].from=v;
 35     edge[tol].to=u;
 36     edge[tol].cap=0;
 37     edge[tol].next=head[v];
 38     head[v]=tol++;
 39 }
 40 void BFS(int start,int end)
 41 {
 42     memset(dep,-1,sizeof(dep));
 43     memset(gap,0,sizeof(gap));
 44     gap[0]=1;
 45     int que[MAXN];
 46     int front,rear;
 47     front=rear=0;
 48     dep[end]=0;
 49     que[rear++]=end;
 50     while(front!=rear)
 51     {
 52         int u=que[front++];
 53         if(front==MAXN)front=0;
 54         for(int i=head[u];i!=-1;i=edge[i].next)
 55         {
 56             int v=edge[i].to;
 57             if(dep[v]!=-1)continue;
 58             que[rear++]=v;
 59             if(rear==MAXN)rear=0;
 60             dep[v]=dep[u]+1;
 61             ++gap[dep[v]];
 62         }
 63     }
 64 }
 65 int SAP(int start,int end)
 66 {
 67     int res=0;
 68     BFS(start,end);
 69     int cur[MAXN];
 70     int S[MAXN];
 71     int top=0;
 72     memcpy(cur,head,sizeof(head));
 73     int u=start;
 74     int i;
 75     while(dep[start]<n)
 76     {
 77         if(u==end)
 78         {
 79             int temp=INF;
 80             int inser;
 81             for(i=0;i<top;i++)
 82                if(temp>edge[S[i]].cap)
 83                {
 84                    temp=edge[S[i]].cap;
 85                    inser=i;
 86                }
 87             for(i=0;i<top;i++)
 88             {
 89                 edge[S[i]].cap-=temp;
 90                 edge[S[i]^1].cap+=temp;
 91             }
 92             res+=temp;
 93             top=inser;
 94             u=edge[S[top]].from;
 95         }
 96         if(u!=end&&gap[dep[u]-1]==0)//出现断层,无增广路
 97           break;
 98         for(i=cur[u];i!=-1;i=edge[i].next)
 99            if(edge[i].cap!=0&&dep[u]==dep[edge[i].to]+1)
100              break;
101         if(i!=-1)
102         {
103             cur[u]=i;
104             S[top++]=i;
105             u=edge[i].to;
106         }
107         else
108         {
109             int min=n;
110             for(i=head[u];i!=-1;i=edge[i].next)
111             {
112                 if(edge[i].cap==0)continue;
113                 if(min>dep[edge[i].to])
114                 {
115                     min=dep[edge[i].to];
116                     cur[u]=i;
117                 }
118             }
119             --gap[dep[u]];
120             dep[u]=min+1;
121             ++gap[dep[u]];
122             if(u!=start)u=edge[S[--top]].from;
123         }
124     }
125     return res;
126 }
127 int main()
128 {
129     int N,P,T;
130     while(~scanf("%d%d%d",&N,&P,&T))
131     {
132         n = N;
133         int left = INF,right = 0;
134         for(int i = 0;i < P;i++)
135         {
136             scanf("%d%d%d",&container[i].from,&container[i].to,&container[i].cap);
137             left = std::min(container[i].cap,left);
138             right = std::max(container[i].cap,right);
139         }
140         left--;
141         while(left + 1 < right)
142         {
143             int mid = (left + right) / 2;
144             init();
145             for(int i = 0;i < P;i++)
146             {
147                 if(container[i].cap <= mid)
148                 {
149                     addedge(container[i].from,container[i].to,1);
150                     addedge(container[i].to,container[i].from,1);
151                 }
152             }
153             if(SAP(1,n) >= T)
154             {
155                 right = mid;
156             }
157             else
158             {
159                 left = mid;
160             }
161         }
162         printf("%d\n",right);
163     }
164     return 0;
165 }

 

转载于:https://www.cnblogs.com/ZShogg/p/3234253.html

购物商城项目采用PHP+mysql有以及html+css jq以及layer.js datatables bootstorap等插件等开发,采用了MVC模式,建立一个完善的电商系统,通过不同用户的不同需求,进行相应的调配和处理,提高对购买用户进行配置….zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值