Magic Potion
網絡流 二分圖模型建圖
- 第一個限制,左邊的點(每個英雄)最多可以流出2的流量,必須讓流入左邊點的流量為2
- 第二個限制,附加流量只有K,不能讓所有的附加邊連接到超級源點,需要限流
建圖
附加一個源點,超級源點和這個源點建一條容量為K的邊,表示有K個瓶子,這個源點和每個英雄建一條容量為1的邊,表示每個瓶子只能被一個英雄用一次
#include <bits/stdc++.h>
#include<cstring>
#define ll long long
using namespace std
;
const int MAXN
= 3010;
const int MAXM
= 1200001;
const int INF
= 0x3f3f3f3f;
struct Edge
{int to
,next
,cap
,flow
,from
;
}edge
[MAXM
];
int tot
,head
[MAXN
];
void init()
{memset(head
,-1,sizeof(head
));tot
=0;
}
void addEdge(int u
,int v
,int w
,int rw
= 0)
{edge
[tot
].to
= v
,edge
[tot
].from
= u
,edge
[tot
].cap
= w
,edge
[tot
].flow
= 0;edge
[tot
].next
= head
[u
];head
[u
] = tot
++;edge
[tot
].to
= u
,edge
[tot
].from
= v
,edge
[tot
].cap
= rw
,edge
[tot
].flow
= 0;edge
[tot
].next
= head
[v
];head
[v
] = tot
++;
}
int Q
[MAXN
];
int dep
[MAXN
],cur
[MAXN
],sta
[MAXN
];
bool bfs(int s
,int t
,int n
)
{int front
= 0,tail
= 0;memset(dep
,-1,sizeof(dep
));dep
[s
] = 0;Q
[tail
++] = s
;while(front
< tail
){int u
=Q
[front
++];for(int i
= head
[u
];i
!= -1;i
=edge
[i
].next
){int v
= edge
[i
].to
;if(edge
[i
].cap
> edge
[i
].flow
&& dep
[v
] == -1){dep
[v
]= dep
[u
] + 1;if(v
== t
) return 1;Q
[tail
++] = v
;}}}return 0;
}
int dinic(int s
,int t
,int n
)
{int maxflow
= 0;while(bfs(s
,t
,n
)){for(int i
= 0;i
<n
;i
++) cur
[i
] = head
[i
];int u
= s
,tail
= 0;while(cur
[s
] != -1){if(u
== t
){int tp
= INF
;for(int i
= tail
-1;i
>= 0;i
--){tp
= min(tp
,edge
[sta
[i
]].cap
-edge
[sta
[i
]].flow
);}maxflow
+= tp
;for(int i
= tail
-1;i
>= 0;i
--){edge
[sta
[i
]].flow
+= tp
;edge
[sta
[i
]^1].flow
-= tp
;if(edge
[sta
[i
]].cap
-edge
[sta
[i
]].flow
== 0) tail
= i
;}u
= edge
[sta
[tail
]^1].to
;}else if(cur
[u
] != -1 && edge
[cur
[u
]].cap
> edge
[cur
[u
]].flow
&& dep
[u
]+1 == dep
[edge
[cur
[u
]].to
]){sta
[tail
++] = cur
[u
];u
= edge
[cur
[u
]].to
;}else{while(u
!= s
&& cur
[u
] == -1){u
= edge
[sta
[--tail
]^1].to
;}cur
[u
] = edge
[cur
[u
]].next
;}}}return maxflow
;
}
void debug()
{for(int i
= 0;i
<tot
;i
+= 2){printf("%d->%d : cap = %d flow = %d\n",edge
[i
].from
,edge
[i
].to
,edge
[i
].cap
,edge
[i
].flow
);}
}int main(){int n
,m
,k
;init();scanf("%d%d%d",&n
,&m
,&k
);int src
=0;int tar
=1+n
+m
+1;int B
=n
+m
+1;addEdge(0,B
,k
);for(int i
=1;i
<=n
;i
++){addEdge(src
,i
,1);addEdge(B
,i
,1);int t
,x
;scanf("%d",&t
);while(t
--){scanf("%d",&x
);addEdge(i
,x
+n
,1);}}for(int i
=1;i
<=m
;i
++)addEdge(i
+n
,tar
,1);int ans
=dinic(src
,tar
,n
+m
+4);printf("%d\n",ans
);
}
Country Meow
最小球覆蓋模板題
模擬淬火算法,起始溫度10w,漸進0.99就過啦
#include<iostream>
#include<map>
#include<string>
#include<cstring>
#include<vector>
#include<algorithm>
#include<set>
#include<sstream>
#include<cstdio>
#include<cmath>
#include<climits>
#include<cstdlib>
using namespace std
;
const double eps
=1e-3;
struct POINT
{double x
,y
,z
;
}p
[110];
POINT op
;
int n
;
inline double dist(POINT
&a
,POINT
&b
){return sqrt((a
.x
-b
.x
)*(a
.x
-b
.x
)+(a
.y
-b
.y
)*(a
.y
-b
.y
)+(a
.z
-b
.z
)*(a
.z
-b
.z
));
}
double solve(){double ret
,delta
=100000.0;double maxDis
,tempDis
;int i
,id
;while(delta
>eps
){id
=0;maxDis
=dist(op
,p
[id
]);for(i
=1;i
<n
;i
++){tempDis
=dist(op
,p
[i
]);if(tempDis
>maxDis
){maxDis
=tempDis
;id
=i
;}}ret
=maxDis
;op
.x
+=(p
[id
].x
-op
.x
)/maxDis
*delta
;op
.y
+=(p
[id
].y
-op
.y
)/maxDis
*delta
;op
.z
+=(p
[id
].z
-op
.z
)/maxDis
*delta
;delta
*=0.999;}return ret
;
}
int main(){while(scanf("%d",&n
)!=EOF&&n
){for(int i
=0;i
<n
;i
++){scanf("%lf%lf%lf",&p
[i
].x
,&p
[i
].y
,&p
[i
].z
);}printf("%lf\n", solve());}return 0;
}
Prime Game
參考博客
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <math.h>
#include <stack>
#include <list>
#include<bits/stdc++.h>
#define MAX 1000005
using namespace std
;
const int N
=1e6+5;
long long su
[MAX
],cnt
;
bool isprime
[MAX
];
void prime()
{cnt
=1;memset(isprime
,1,sizeof(isprime
));isprime
[0]=isprime
[1]=0;for(long long i
=2; i
<MAX
; i
++){if(isprime
[i
])su
[cnt
++]=i
;for(long long j
=1; j
<cnt
&&su
[j
]*i
<MAX
; j
++){isprime
[su
[j
]*i
]=0;}}
}
int a
[N
];
vector
<long long>mp
[MAX
];
void init(int x
,int pos
)
{for(int i
=1; su
[i
]*su
[i
]<=x
; i
++){if(x
%su
[i
]==0){mp
[su
[i
]].push_back(pos
);while(x
%su
[i
]==0)x
/=su
[i
];}}if(x
>1){mp
[x
].push_back(pos
);}
}
int main()
{prime();long long n
;while(scanf("%lld",&n
)!=EOF){for(int i
=1;i
<cnt
;i
++)mp
[su
[i
]].clear();for(int i
=1; i
<=n
; i
++){scanf("%d",&a
[i
]);init(a
[i
],i
);}long long ans
=0;for(int i
=1; i
<cnt
; i
++){if(mp
[su
[i
]].size()==0)continue;else{ans
+=mp
[su
[i
]][0]*(n
-mp
[su
[i
]][0]+1);for(int j
=1; j
<mp
[su
[i
]].size(); j
++)ans
+=(mp
[su
[i
]][j
]-mp
[su
[i
]][j
-1])*(n
-mp
[su
[i
]][j
]+1);}}printf("%lld\n",ans
);}return 0;
}
線性篩模板
int Mark
[Max
];
int prime
[Max
];
int Prime(){ int index
= 0; memset(Mark
,0,sizeof(Mark
)); for(int i
= 2; i
< Max
; i
++){ if(Mark
[i
] == 0){ prime
[index
++] = i
; } for(int j
=0; j
<index
&& prime
[j
]*i
< Max
; j
++){ Mark
[i
* prime
[j
]] = 1; if(i
% prime
[j
] == 0){ break; } } } return index
;
}
總結
以上是生活随笔為你收集整理的2018ACM-ICPC Asia Nanjing Regional Contest的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。