BZOJ2055 80人環遊世界

2022-05-12 00:45:12 字數 4013 閱讀 8769

題解:

總算a掉了,各種蛋疼。。。

int

main()

for1(i,n)for2(j,i+1,n)

for1(i,n)insert(i+n,t,0,inf,0

); insert(t,s,

0,inf,0

); mcf();

printf(

"%d\n

",mincost);

return0;

}

s是附加源,sss是真正的源,t是真正的匯。這樣構圖就好了,但我們還有下界限制,那再來個ss,tt。。。居然還是費用流。。。然後這題就做完了

因為我們只需要最小費用,所以我們只需求出可行流&最小費用即可。

關於下界的處理我直接寫在insert函式裡。。。導致慢成翔。。。

**:

1 #include2 #include3 #include4 #include5 #include6 #include7 #include8 #include9 #include

10 #include11 #include

12#define inf 1000000000

13#define maxn 200000

14#define maxm 200000

15#define eps 1e-10

16#define ll long long

17#define pa pair18

#define for0(i,n) for(int i=0;i<=(n);i++)

19#define for1(i,n) for(int i=1;i<=(n);i++)

20#define for2(i,x,y) for(int i=(x);i<=(y);i++)

21#define for3(i,x,y) for(int i=(x);i>=(y);i--)

22#define for4(i,x) for(int i=head[x],y;i;i=e[i].next)

23#define mod 1000000007

24using

namespace

std;

25 inline int

read()

2629

while(ch>='

0'&&ch<='9')

30return x*f;31}

32int n,m,k,mincost,tot=1,s,t,ss,tt,sss,head[maxn],d[maxn],from[2*maxm];

33bool

v[maxn];

34 queueq;

35struct edgee[2*maxm];

36void ins(int x,int y,int v,int

c)37

;head[x]=tot;

39 e[++tot]=(edge);head[y]=tot;40}

41void insert(int x,int y,int l,int r,int

c)42

45bool

spfa()

4648 q.push(ss);d[ss]=0;v[ss]=1;49

while(!q.empty())

5057}58

}59return d[tt]!=inf;60}

61void

mcf()

6270}71

}72intmain()

7380 for1(i,n)for2(j,i+1,n)

81 for1(i,n)insert(i+n,t,0,inf,0

);82 insert(t,s,0,inf,0

);83

mcf();

84 printf("

%d\n

",mincost);

85return0;

86 }

view code

upd:把邊合併了之後用時成了1/4

**:

1 #include2 #include3 #include4 #include5 #include6 #include7 #include8 #include9 #include

10 #include11 #include

12#define inf 1000000000

13#define maxn 200000

14#define maxm 200000

15#define eps 1e-10

16#define ll long long

17#define pa pair18

#define for0(i,n) for(int i=0;i<=(n);i++)

19#define for1(i,n) for(int i=1;i<=(n);i++)

20#define for2(i,x,y) for(int i=(x);i<=(y);i++)

21#define for3(i,x,y) for(int i=(x);i>=(y);i--)

22#define for4(i,x) for(int i=head[x],y;i;i=e[i].next)

23#define mod 1000000007

24using

namespace

std;

25 inline int

read()

2629

while(ch>='

0'&&ch<='9')

30return x*f;31}

32int n,m,k,mincost,tot=1,s,t,ss,tt,sss,head[maxn],d[maxn],from[2*maxm],in

[maxn];

33bool

v[maxn];

34 queueq;

35struct edgee[2*maxm];

36void ins(int x,int y,int v,int

c)37

;head[x]=tot;

39 e[++tot]=(edge);head[y]=tot;40}

41void insert(int x,int y,int l,int r,int

c)42

47void

build()

4852

bool

spfa()

5355 q.push(ss);d[ss]=0;v[ss]=1;56

while(!q.empty())

5764}65

}66return d[tt]!=inf;67}

68void

mcf()

6977}78

}79intmain()

8087 for1(i,n)for2(j,i+1,n)

88 for1(i,n)insert(i+n,t,0,inf,0

);89 insert(t,s,0,inf,0

);90

build();

91mcf();

92 printf("

%d\n

",mincost);

93return0;

94 }

view code

time limit: 10 sec  memory limit: 64 mb

submit: 116  solved: 75

[submit][status]

第一行兩個正整數n,m。第二行有n個不大於m正整數,分別表示v1,v2......vn。接下來有n ¡ 1行。第i行有n ¡ i個整數,該行的第j個數表示從第i個國家到第i + j個國家的機票費(如果該值等於¡1則表示這兩個國家間沒有通航)。

在第一行輸出最少的總費用。

6 32 1 3 1 2 1

2 6 8 5 0

8 2 4 1

6 1 0

4 -1427

1<= n < =100 1<= m <= 79

bzoj 2055 80人環遊世界

有源匯上下界最小費用可行流。將每個國家拆點。源點向乙個新建節點連一條上界為總人數下界為0費用為0的邊。新建節點向每個國家的入點連一條上界為正無窮下界為0費用為0的邊。每個國家的入點向出點連一條上下界均為該國家訪問人數費用為0的邊。每個國家的出點向匯點連一條上界為正無窮下界為0費用為0的邊。對於國家i...

BZOJ2055 80人環遊世界

上下界最小費用流 限制點訪問量 拆點 i,i 建圖 1.s s m,m 0 2.s i 0,inf 0 i t 0,inf 0 3.i j 0,inf x 4.i i vi,vi 0 然後就是上下界流的常見套路啦 根據 調整 原則 先是每個點點權為di ini outi 然後 0的連源點 0的連匯點...

bzoj2055 80人環遊世界(可行流)

傳送門 表示完全看不懂最小費用可行流 據某大佬說 我們考慮拆點,然後進行如下連邊 s 向 a i 連邊,權值 0 容量 0,m a i 向 a i 連邊,權值 0 容量 v i,v i 如果存在邊 i,j 則連邊 a i a i 權值為 w 容量 0,m a i 向 t 連邊,權值 0 容量 0,m...