usaco4.4.2
2012-03-15 17:07
106 查看
题目大意:
给定一个网络,求该网络的最小割,并求割边最少的割集,并按字典序最小输出割集。
1、求最小割应该不难,根据最大流最小割定理,直接跑一趟最大流就可以了
2、第二问求割边最少的割集小闹。其实可以通过对边的容量进行修改来完成。
一般情况下,我们的容量就是输入的c,但是这里我们把它改成c*(m+1)+1,m为边的总数目
为什么这样呢?
这里有两个因素,一个是割要最小,另一个是边数要最少。
这就相当于一个双关键字排序,最后的那个加一就像当于把这条边加入,但是这条边的加入不能影响最小割的值,那么最多有1000条边,为了
让它不影响最小割,所以容量应该乘以总边数。
3、按字典序输出割集中的所有边。
这个子问题可以枚举所有边,如果去掉该边后的最大流量/最小割+该边容量等于原来的最大流量/最小割,那么该边是割集中的。
另外:用dinic加上long long目测时间比较费,sap的效率比较高。看了fhq的文章,该好好去研究一下sap了
给定一个网络,求该网络的最小割,并求割边最少的割集,并按字典序最小输出割集。
1、求最小割应该不难,根据最大流最小割定理,直接跑一趟最大流就可以了
2、第二问求割边最少的割集小闹。其实可以通过对边的容量进行修改来完成。
一般情况下,我们的容量就是输入的c,但是这里我们把它改成c*(m+1)+1,m为边的总数目
为什么这样呢?
这里有两个因素,一个是割要最小,另一个是边数要最少。
这就相当于一个双关键字排序,最后的那个加一就像当于把这条边加入,但是这条边的加入不能影响最小割的值,那么最多有1000条边,为了
让它不影响最小割,所以容量应该乘以总边数。
3、按字典序输出割集中的所有边。
这个子问题可以枚举所有边,如果去掉该边后的最大流量/最小割+该边容量等于原来的最大流量/最小割,那么该边是割集中的。
另外:用dinic加上long long目测时间比较费,sap的效率比较高。看了fhq的文章,该好好去研究一下sap了
/* ID: volz.kz.g PROB: milk6 LANG: C++ */ #include <iostream> #include <fstream> #include <cstring> using namespace std; typedef long long LL; ifstream fin("milk6.in"); ofstream fout("milk6.out"); const LL maxLL = 0x7FFFFFFF; struct edge_node{ LL v,c,next; }e[2200]; edge_node e_backup[2200]; bool e_use[2200]; bool interview[2000]; LL v[100],d[100],c[100]; LL n,m,edge_num; LL ans,ans1,ans_num; LL ans_seq[2200]; int s,t; inline void insert(int a,int b,int cc){ edge_num++;e[edge_num].v=b;e[edge_num].c=cc*(m+1)+1;e[edge_num].next=v[a];v[a]=edge_num; edge_num++;e[edge_num].v=a;e[edge_num].c=0;e[edge_num].next=v[b];v[b]=edge_num; } inline int opp(int x){ return (x%2==1)?x+1:x-1; } inline LL maxflow(int x,LL lim){ LL min_num,max_flow,ret;int i,j; if (x==t) return lim; min_num=n;max_flow=0;j=v[x]; while (j!=0){ if (e[j].c>0 && e_use[j]){ if (d[e[j].v]+1==d[x]){ ret=min(lim,e[j].c);ret=maxflow(e[j].v,ret); e[j].c-=ret;e[opp(j)].c+=ret; lim-=ret;max_flow+=ret; if (lim==0 || d[s]>=t) return max_flow; } min_num=min(min_num,d[e[j].v]+1); } j=e[j].next; } if (min_num==d[x]) return max_flow; c[d[x]]--;if (c[d[x]]==0) d[s]=t; d[x]=min_num;c[d[x]]++; return max_flow; } inline void save(){ for (int i=1;i<=2*m;i++) e_backup[i]=e[i]; } inline void backup(){; for (int i=1;i<=2*m;i++) e[i]=e_backup[i]; } int main(){ int a,b,cc; fin >> n >> m; memset(e_use,true,sizeof(e_use));memset(interview,true,sizeof(interview)); for (int i=1;i<=m;i++) fin >> a >> b >> cc,insert(a,b,cc); save(); s=1;t=n;c[0]=n; while (d[s]<t) ans+=maxflow(s,maxLL); LL ans_amount = ans/(m+1); LL ans_chuck_num = ans%(m+1); LL tmp=ans_chuck_num; fout << ans_amount << " " << ans_chuck_num << endl; for (int i=1;i<=m;i++){ backup();e_use[2*i-1]=false;e_use[2*i]=false; memset(c,0,sizeof(c));memset(d,0,sizeof(d)); s=1;t=n;c[0]=n;ans1=0; while (d[s]<t) ans1+=maxflow(s,maxLL); if (ans1+e[2*i-1].c==ans){ ans_seq[ans_num++]=i; ans=ans1; tmp--; if (tmp==0) break; } else e_use[2*i-1]=true,e_use[2*i]=true; } for (int i=0;i<ans_num;i++) fout << ans_seq[i] << endl; }
相关文章推荐
- usaco 4.4.2 Pollutant Control
- [USACO4.4.2 Pollutant Control]
- usaco --4.4.2--Pollutant Control
- USACO 4.4.2 milk6
- 【USACO4.4.2】追查坏牛奶(BSOI2140)
- USACO4.4.2 Pollutant Control (milk6)
- C++——【USACO 4.4.2】——Pollutant Control
- usaco training 4.4.2 Pollutant Control 追查坏牛奶 题解
- USACO4.4.2 Pollutant Control (milk6)
- USACO 4.4.2 Pollutant Control追查坏牛奶 题解与分析
- 【usaco】4.4.2最小割集PROB Pollutant Control
- USACO 2014 February Contest, Silver
- USACO Prime Palindromes
- 【bzoj1598】【 [Usaco2008 Mar]牛跑步】启发式搜索思路+spfa
- USACO 3.1 Humble Numbers (humble)
- USACO Wormholes 解题日志
- USACO Corn Fields
- USACO 3.2 Sweet Butter (butter)
- 土地购买[Usaco2008 Mar][bzoj 1597]
- [USACO 13NOV]No Change