Alice and Bob
排序问题:hdu2523,hdu5884,hdu1880
//hdu5884使用二分查找以及优先队列降低时间复杂度
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ok cout<<"ok\n";
#define INF 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
#define f(a,b,c) for(register int a=b;a<=c;a++)
inline ll read() {
ll x=0,f=1;
char c=getchar();
while(c<'0'||c>'9') {
if(c=='-')f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=(x<<1)+(x<<3)+c-'0';
c=getchar();
}
return x*f;
}
int a[100001],sum[100001];
int n,t,mid;
priority_queue<int,vector<int>,greater<int > >q;
bool check(int k) {
while(q.empty()==false) q.pop();
int m=(n-1)%(k-1);
int ans=0;
if(m) {
m++;
ans=sum[m];
q.push(ans);
}
f(i,m+1,n) q.push(a[i]);
int w=(n-1)/(k-1);
f(i,1,w) {
int cnt=0;
f(j,0,k-1) {
cnt+=q.top();
q.pop();
}
ans+=cnt;
q.push(cnt);
}
if(ans<=t) return true;
else return false;
}
int main() {
int m=read();
while(m--) {
n=read(),t=read();
int ans;
a[0]=0;
f(i,1,n) a[i]=read();
sort(a+1,a+1+n);
f(i,1,n) sum[i]=sum[i-1]+a[i];
int l=2,r=n;
while(l<r) {
mid=(l+r)>>1;
if(check(mid)==true) r=mid;
else l=mid+1;
}
if(n<=1) r=1;
cout<<r<<endl;
}
return 0;
}
优先队列 hdu1873 hdu1896
全排列 hdu6628 pku Backward Digit Sums
并查集题目合集: More is better
Cube Stacking Farm Irrigation
小希的迷宫 Dragon Balls
Find them, Catch them
Wireless Network
食物链(这边用3倍的数组主要因为是一个环,看图!!)
LCA倍增法
并查集食物链
find and catch
iddfs例题
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <string>
#include <sstream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
#include <list>
#define the_best_pony "Rainbow Dash"
using namespace std;
int n,maxh;
int a[1010];
bool dfs(int x,int cur){
cout<<" x= "<<x<<" cur= "<<cur<<" , "<<endl;
//if(x<<(maxh-cur)<n) return false; //乐观估计剪枝,当前深度到限制深度指数最多增长2^(maxh-cur)倍
if(cur>maxh) return false; //达到限制深度
a[cur]=x;
if(x==n) return true;
for(int i=0;i<=cur;i++){
if(dfs(x+a[i],cur+1)) return true;
if(dfs(x>a[i]?x-a[i]:a[i]-x,cur+1)) return true;
}
return false;
}
int main(){
while(scanf("%d",&n)&&n){
maxh=0;
memset(a,0,sizeof(a));
while(!dfs(1,0)){ //只要没找到答案就一直继续
memset(a,0,sizeof(a));
maxh++; //增大深度限制
}
printf("%d\n",maxh); //最大深度就是答案
}
return 0;
}
二叉树专题:{
Splay树(伸展树)hdu 4453 Looploop
字典树
hdu1545 树与并查集
}
分治法//二分答案
hdu1007
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ok cout<<"ok\n";
#define INF 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
#define f(a,b,c) for(register int a=b;a<c;a++)
#define hh puts("")
#define IOS ios::sync_with_stdio(false)
#define pii pair<int,int>
#define mod 1000000007
#define ull unsigned long long
inline ll read(){
ll x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
return x*f;
}
struct node{
double x,y;
};
node*pa[100001],*pb[100001];node point[100001];
bool cmpx(node *p1,node *p2) {return p1->x<p2->x;}
bool cmpy(node *p1,node *p2) {return p1->y<p2->y;}
double min(double a,double b){return a<b?a:b;}
double dis(node*p1,node*p2){
return sqrt((p1->x-p2->x)*(p1->x-p2->x)+(p1->y-p2->y)*(p1->y-p2->y));
}
double closest(int l,int r){
if(l+1==r) return dis(pa[l],pa[r]);
if(l+2==r) return min(min(dis(pa[l],pa[l+1]),dis(pa[l+1],pa[r])),dis(pa[l],pa[r]));
int mid=(l+r)>>1;
double llength=closest(l,mid);
double rlength=closest(mid+1,r);
double ans=min(llength,rlength);
int cnt=0;
f(i,l,r){
if(pa[i]->x>=pa[mid]->x-ans&&pa[i]->x<=pa[mid]->x+ans) pb[cnt++]=pa[i];
}
sort(pb,pb+cnt,cmpy);
f(i,0,cnt){
f(j,i+1,cnt){
if(pb[j]->y-pb[i]->y>ans) break;
ans=min(ans,dis(pb[j],pb[i]));
}
}
return ans;
}
int main(){
int n;
while(scanf("%d",&n)){
if(n==0) break;
f(i, 0, n){
scanf("%lf%lf",&point[i].x,&point[i].y);
pa[i]=&point[i];
}
sort(pa,pa+n,cmpx);
double distance=closest(0,n-1);
printf("%.2lf\n",distance/2);
}
return 0;
}
hdu1969
#include<bits/stdc++.h>
#define PI acos(-1.0)
using namespace std;
double n,f;
double size[100000];
bool check(double ans) {
int aa=0;
for(int i=0; i<n; i++) {
aa+=(int)pow(size[i]/ans, 2);
// aa+=int(pow((size[i]/ans),2));
}
//cout<<ans<<" check "<<aa<<" "<<n+1<<endl;
if(aa>=f+1) return false;
return true;
}
double answer;
void find(double l,double r) {
if(r-l<=1e-10){
answer=l;
return;
}
double mid=(l+r)/2.0;
if(check(mid)){
// cout<<"l== "<<l<<endl;
find(l,mid);
}
else {
// cout<<"wrongl== "<<l<<endl;
find(mid,r);
}
}
int main() {
int t;
scanf("%d",&t);
while(t--) {
scanf("%lf%lf",&n,&f);
double maxx=0.00;
for(int i=0; i<n; i++) {
scanf("%lf",&size[i]);
maxx=max(size[i],maxx);
}
//double bb=);
double l=0.00;find(l,maxx);
printf("%.4f\n", PI*pow(answer, 2));
// cout<<<<endl;
}
return 0;
}
链式前向星板子(用链式前向星写prim和克鲁斯卡尔拓扑排序!!!!)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 1e5+10;
int head[N],idx;
struct Edge
{
int next;//当前点所指向的下一个点
int to; //边所指向的点
int val; //边的权值
}edge[N];
void add(int u,int v,int w)
{
edge[idx].val = w;
edge[idx].to = v;
edge[idx].next = head[u];
head[u] = idx++;
}
int main ()
{
int n,m;
scanf("%d%d",&n,&m);
while(m -- )
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
}
memset(head,-1,sizeof(head));
for (int i = 1; i <= n; i++ )
{
for (int j = head[i]; j != -1; j = edge[j].next)
{
printf("%d->%d的权值为%d\n",i,edge[j].to,edge[j].val);
}
}
return 0;
}
//vector版dijkstra
#include<bits/stdc++.h>
using namespace std;
#define ok cout<<"ok\n";
const int maxn=1e5;
const int INF=1e6;
struct edge {
int from,to,weight;
edge(int a,int b,int c) {
from=a;
to=b;
weight=c;
}
};
vector<edge>e[maxn];
struct node {
int id,dis;
node(int b,int c) {
id=b;
dis=c;
}
operator<(const node&a) const {
return dis>a.dis;
}
};
int n,m;
int pre[maxn];
void print_path(int s,int t){
if(s==t){
printf(" %d ", s);
return;
}
print_path(s,pre[t]);
printf("%d ",t);
}
void dijks(){
int dis[maxn];
bool down[maxn];
for(int i=1;i<=n;i++){
dis[i]=INF;
down[i]=false;
}
dis[1]=0;
priority_queue<node> Q;
Q.push(node(1,dis[1]));
while(Q.empty()==false){
node u=Q.top();
Q.pop();
if(down[u.id]) continue;
down[u.id]=true;
for(int i=0;i<e[u.id].size();i++){
edge y=e[u.id][i];
if(down[y.to]) continue;
if(dis[y.to]>y.weight+u.dis) {
dis[y.to]=y.weight+u.dis;
Q.push(node(y.to,dis[y.to]));
}
}
}
printf("%d\n",dis[n]);
}
int main() {
//freopen("1.txt","r",stdin);
while(~scanf("%d%d",&n,&m)&&n|m){
for(int i=1;i<=n;i++) e[i].clear();
while(m--){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
e[a].push_back(edge(a,b,c));
e[b].push_back(edge(b,a,c));
}
dijks();
}
return 0;
}
//DINIC
#include <iostream>
#include <queue>
using namespace std;
const int INF = 0x7fffffff;
int V, E;
int level[205];
int Si, Ei, Ci;
struct Dinic
{
int c;
int f;
}edge[205][205];
bool dinic_bfs() //bfs方法构造层次网络
{
queue<int> q;
memset(level, 0, sizeof(level));
q.push(1);
level[1] = 1;
int u, v;
while (!q.empty()) {
u = q.front();
q.pop();
for (v = 1; v <= E; v++) {
if (!level[v] && edge[u][v].c>edge[u][v].f) {
level[v] = level[u] + 1;
q.push(v);
}
}
}
return level[E] != 0; //question: so it must let the sink node is the Mth?/the way of yj is give the sink node's id
}
int dinic_dfs(int u, int cp) { //use dfs to augment the flow
int tmp = cp;
int v, t;
if (u == E)
return cp;
for (v = 1; v <= E&&tmp; v++) {
if (level[u] + 1 == level[v]) {
if (edge[u][v].c>edge[u][v].f) {
t = dinic_dfs(v, min(tmp, edge[u][v].c - edge[u][v].f));
edge[u][v].f += t;
edge[v][u].f -= t;
tmp -= t;
}
}
}
return cp - tmp;
}
int dinic() {
int sum=0, tf=0;
while (dinic_bfs()) {
while (tf = dinic_dfs(1, INF))
sum += tf;
}
return sum;
}
int main() {
while (scanf("%d%d", &V, &E)) {
memset(edge, 0, sizeof(edge));
while (V--) {
scanf("%d%d%d", &Si, &Ei, &Ci);
edge[Si][Ei].c += Ci;
}
int ans = dinic();
printf("%d\n", ans);
}
return 0;
}
//ISPA
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
int y,c,next;
}a[210000];int len=1,last[21000],st,ed;
int num[21000],cur[21000],qian[21000],h[21000],n,m;
int mymin(int x,int y){return x<y?x:y;}
void ins(int x,int y,int c)
{
len++;
a[len].y=y;a[len].c=c;a[len].next=last[x];last[x]=len;
len++;
a[len].y=x;a[len].c=0;a[len].next=last[y];last[y]=len;
}
int list[21000],head,tail;
void bfs()
{
head=1;tail=2;list[head]=ed;h[ed]=1;num[1]++;
while(head!=tail)
{
int x=list[head];
for(int k=last[x];k;k=a[k].next)
{
if(h[a[k].y]==0 && a[k^1].c>0)
{
num[h[a[k].y]=h[x]+1]++;
list[tail++]=a[k].y;
}
}
head++;
}
if(h[st]==0)h[st]=n+1;
}
int add()
{
int now=ed,ans=999999999;
while(now!=st)
{
ans=mymin(ans,a[qian[now]].c);
now=a[qian[now]^1].y;
}
now=ed;
while(now!=st)
{
a[qian[now]].c-=ans;a[qian[now]^1].c+=ans;
now=a[qian[now]^1].y;
}
return ans;
}
int findflow()
{
int ans=0,now=st;
bfs();
while(h[st]<=n)
{
bool bk=true;
while(bk==true)
{
bk=false;
for(int k=cur[now];k;k=a[k].next)
{
if(a[k].c>0 && h[a[k].y]+1==h[now])
{
bk=true;
cur[now]=k;
now=a[k].y;
qian[now]=k;
break;
}
}
if(now==ed)
{
ans+=add();now=st;
}
}
if((--num[h[now]])==0)break;
num[++h[now]]++;cur[now]=last[now];
if(now!=st)now=a[qian[now]^1].y;
}
return ans;
}
int main()
{
scanf("%d%d%d%d",&n,&m,&st,&ed);
for(int i=1;i<=m;i++)
{
int x,y,c;scanf("%d%d%d",&x,&y,&c);
ins(x,y,c);
}
for(int i=1;i<=n;i++)cur[i]=last[i];
printf("%d\n",findflow());
return 0;
}