【apio 2012】ネットワークフロー
apioは行かなかったが、授業資料は研究に値する.
2~4番の問題はまだあまり見たことがないので、他のいくつかの問題は比較的に年を取っています.
Transform Matrix
mtはwc 2010の校内授業で話したことがありますが、この問題を聞いたことしか覚えていませんが、改めて考えがはっきりしています.まず、任意の1を他の数字に影響を与えずに0に移動することができます.0と仮定すると直接交換します.1であれば、リレーと見なすことができます.1は等価なので、通り抜けることと見なすことができます.では,初期状態の1とターゲット状態の1を1つずつ対応させ,経路の制限をうまく処理すればよいが,この部分は直接最大流にすることができる.
ロード城への道
実はこの問題は省が選ぶ前に私はまだしていなかったが、やり方が奇抜だと聞いただけで、ネットの流れのやり方があるとは思わなかった.私は1つのテーマの性質を無視して、つまりa[i]でh[i]-h[i+1]を表すならば、a[i]-1ならば、きっとあるa[j]+1は費用が異なるだけで(構造することができて、中間hの同昇同降を通じて)、私たちの任務はすべてのaを指定区間[-c,c]に調整することに転換して、調整方式は再分配して1をプラスして1を減らして、しかも費用があって、これは上下境界を伴う最小費用実行フローで実現できる.
この問題は次の問題の構想とは逆に(後で述べる)、主に思想を調整し(これもネットワークストリームの古典的な最適化の面である)、混合図のようなオラ回路は、トラフィックを通じて再分配される.
この問題は元の対偶費用の流れを使って、涛兄の奇抜なアルゴリズムより速く走った.
2010年にウトロ郷を建設する難題がある.
難題のデータ&テーマを求めます
特殊な点と一般的な点があります
各エッジの端点の少なくとも1つの特殊な点は、
各ポイントの権限値
L
を選択します.
c*|ΔL[
i
]|,
エッジ
(
i
,j
)
対価を計算するには
e*|L[
i
]-L[j]|,
求める
min{c*Σ|ΔL[
i
]|+e*Σ|L[
i
]-L[j
]|},
L
のみ
1~20
の整数
この問題の場合、前の問題の調整思想に沿っていると思いますが、中間状態が複雑すぎて考えられず(本当に弱い)、特殊点がつながっていない場合を考えると、いずれかの特殊点がある値を取る費用は確かですが、2つの特殊点がつながっていると、1つの点のLを変えると互いに新しい費用が発生し、中間関係を無視して,i番目の点Lをb[i,j]でjとして表し,図b[i,j]からb[i,j+1]への重みをcost[i,j](特殊点の費用を考慮しない)とし,特殊点,b[u,j]からb[v,j]への重みをeの辺とすると仮定すると,最小割開の場合,必ずuとvのL値の差がある層中間の点の重みe辺が割開され,費用案に対応する.したがって、最小割合は求められる.
主な考え方は,中間状態の変化を考慮せずに最終状態を直接決定する費用(少し運動エネルギーの定理に似ている)であるべきである.
2~4番の問題はまだあまり見たことがないので、他のいくつかの問題は比較的に年を取っています.
Transform Matrix
mtはwc 2010の校内授業で話したことがありますが、この問題を聞いたことしか覚えていませんが、改めて考えがはっきりしています.まず、任意の1を他の数字に影響を与えずに0に移動することができます.0と仮定すると直接交換します.1であれば、リレーと見なすことができます.1は等価なので、通り抜けることと見なすことができます.では,初期状態の1とターゲット状態の1を1つずつ対応させ,経路の制限をうまく処理すればよいが,この部分は直接最大流にすることができる.
ロード城への道
実はこの問題は省が選ぶ前に私はまだしていなかったが、やり方が奇抜だと聞いただけで、ネットの流れのやり方があるとは思わなかった.私は1つのテーマの性質を無視して、つまりa[i]でh[i]-h[i+1]を表すならば、a[i]-1ならば、きっとあるa[j]+1は費用が異なるだけで(構造することができて、中間hの同昇同降を通じて)、私たちの任務はすべてのaを指定区間[-c,c]に調整することに転換して、調整方式は再分配して1をプラスして1を減らして、しかも費用があって、これは上下境界を伴う最小費用実行フローで実現できる.
この問題は次の問題の構想とは逆に(後で述べる)、主に思想を調整し(これもネットワークストリームの古典的な最適化の面である)、混合図のようなオラ回路は、トラフィックを通じて再分配される.
この問題は元の対偶費用の流れを使って、涛兄の奇抜なアルゴリズムより速く走った.
#include <cstdio>
#include <cstdlib>
#include <cstring>
const long long oo=1073741819102LL;
int s,t,s1,t1,n,m,ss,time;
long long ans,phi;
int tail[100000],v[100000],flag[100000];
int next[2000000],sora[2000000],pow[2000000],st[2000000],p[100000],cost[2000000];
long long flow[2000000],ru[100000],chu[100000],d[100000],tmp,h[100000];
int spfa(int s,int t)
{
int h,r,i,j,ne,na;
// memset(d,127,sizeof(d));
for (i=1;i<=t;i++) d[i]=oo;
h=r=0;
st[r=1]=t,d[t]=0,v[t]=1;
for (;h<r;) {
ne=st[++h];
for (i=ne;next[i]!=0;) {
i=next[i],na=sora[i];
if (flow[pow[i]] && d[ne]+cost[pow[i]]<d[na]) {
d[na]=d[ne]+cost[pow[i]];p[na]=ne;
if (!v[na]) v[na]=1,st[++r]=na;
}
}
v[ne]=0;
}
if (d[s]>=oo) return 0;
phi+=d[s];
for (i=1;i<=t;i++)
for (j=i;next[j]!=0;) {
j=next[j],ne=sora[j];
cost[j]-=d[i]-d[ne];
}
return 1;
}
long long dfs(int x,long long low)
{
if (t1==x) {ans+=phi*low;return low;}
int i,ne;
long long sum=0;
flag[x]=time;
for (i=x;next[i]!=0;) {
i=next[i],ne=sora[i];
if (flow[i] && !cost[i] && flag[ne]!=time) {
if (flow[i]<low) tmp=dfs(ne,flow[i]);
else tmp=dfs(ne,low);
flow[i]-=tmp,flow[pow[i]]+=tmp,sum+=tmp,low-=tmp;
if (!low) break;
}
}
return sum;
}
void origin()
{
s=n+1,t=s+1,s1=t+1,t1=s1+1,ss=t1;
for (int i=1;i<=t1;i++) tail[i]=i,ru[i]=chu[i]=next[i]=0;
}
void link2(int x,int y,long long z,long long c)
{
ss++,next[tail[x]]=ss,tail[x]=ss,sora[ss]=y,flow[ss]=z,cost[ss]=c,next[ss]=0;
ss++,next[tail[y]]=ss,tail[y]=ss,sora[ss]=x,flow[ss]=0,cost[ss]=-c,next[ss]=0;
pow[ss]=ss-1,pow[ss-1]=ss;
}
void link(int x,int y,long long low,long long lim,long long c)
{
chu[x]+=low,ru[y]+=low;ans+=low*c;
link2(x,y,lim-low,c);
}
void init()
{
int i;
long long x,c;
scanf("%d%I64d
",&n,&c);ans=0;
origin();
for (i=1;i<=n;i++) scanf("%I64d",&h[i]);
for (i=1;i<=n-1;i++) {
x=h[i]-h[i+1];
// if (x<-c) link(s,i,-c-x,c-x,1);else if (x>c) link(i,t,x-c,x+c,0);
if (x<-c) link(i,t,-c-x,c-x,0);else if (x>c) link(s,i,x-c,x+c,0);
else link(s,i,0,x+c,0),link(i,t,0,c-x,0);
}
for (i=1;i<=n-2;i++) link(i,i+1,0,oo,1),link(i+1,i,0,oo,1);
link(t,s,0,oo,0);
for (i=1;i<=t;i++)
if (ru[i]>chu[i]) link2(s1,i,ru[i]-chu[i],0);
else if (ru[i]<chu[i]) link2(i,t1,chu[i]-ru[i],0);
for (phi=0;spfa(s1,t1);)
for (;time++, dfs(s1,oo) ;) ;
for (i=s1;next[i]!=0;) {
i=next[i];
if (flow[i]) {printf("impossible
");return ;}
}
printf("%I64d
",ans);
}
int main()
{
freopen("road.in","r",stdin);
freopen("road.out","w",stdout);
int t;
scanf("%d
",&t);
for (;t;t--) init();
return 0;
}
2010年にウトロ郷を建設する難題がある.
難題のデータ&テーマを求めます
特殊な点と一般的な点があります
各エッジの端点の少なくとも1つの特殊な点は、
各ポイントの権限値
L
を選択します.
c*|ΔL[
i
]|,
エッジ
(
i
,j
)
対価を計算するには
e*|L[
i
]-L[j]|,
求める
min{c*Σ|ΔL[
i
]|+e*Σ|L[
i
]-L[j
]|},
L
のみ
1~20
の整数
この問題の場合、前の問題の調整思想に沿っていると思いますが、中間状態が複雑すぎて考えられず(本当に弱い)、特殊点がつながっていない場合を考えると、いずれかの特殊点がある値を取る費用は確かですが、2つの特殊点がつながっていると、1つの点のLを変えると互いに新しい費用が発生し、中間関係を無視して,i番目の点Lをb[i,j]でjとして表し,図b[i,j]からb[i,j+1]への重みをcost[i,j](特殊点の費用を考慮しない)とし,特殊点,b[u,j]からb[v,j]への重みをeの辺とすると仮定すると,最小割開の場合,必ずuとvのL値の差がある層中間の点の重みe辺が割開され,費用案に対応する.したがって、最小割合は求められる.
主な考え方は,中間状態の変化を考慮せずに最終状態を直接決定する費用(少し運動エネルギーの定理に似ている)であるべきである.