1001 hdu 3401
刚刚学过的单调队列
难度:4星
http://hi.baidu.com/edwardmj/blog/item/82fcbcc49ecc4f179d163d21.html
这个解题报告写得很清楚
1002 hdu 3452 Bonsai
题意:给你一棵树,每条边有一个权值,问你想让all leaf 和 root 不连通,至少要去掉的value
难度:2星
思路:搜索
想要使任一节点下的all leaf和它父节点不联通无非2 methods:
1.使该节点和父节点不联通(1条边)
2.使该节点和所有叶子不联通
use edge[x].ver[i][0] to record the index of the i-th edge vertex x connects
use edge[x].ver[i][1] to record the value of the edge above
那么对于root来说,cost=所有min(edge[r].ver[i][1],dfs(edge[r].ver[j][0]))的和
#include<iostream>
using namespace std;
int n,r;
struct EDGE
{
int ver[1010][2];//weight;
}edge[1010];
bool visited[1010];
int deg[1010];
int dfs(int root)
{
visited[root]=true;
int temp=0;
int ori=0;
if(deg[root]==1)
return edge[root].ver[1][1];
for(int i=1;i<=deg[root];i++)
{
if(!visited[edge[root].ver[i][0]])
{
temp+=dfs(edge[root].ver[i][0]);
}
else
ori=edge[root].ver[i][1];
}
return temp<ori?temp:ori;
}
void init()
{
int from,to,w;
for(int k=1;k<n;k++)
{
scanf("%d%d",&from,&to);
scanf("%d",&w);
edge[from].ver[++deg[from]][0]=to;
edge[to].ver[++deg[to]][0]=from;
edge[from].ver[deg[from]][1]=w;
edge[to].ver[deg[to]][1]=w;
}
}
int main()
{
while(scanf("%d%d",&n,&r)!=EOF&&(n||r))
{
for(int i=0;i<=n;i++)
{
deg[i]=0;
visited[i]=false;
}
init();
int t=0;
visited[r]=true;
for(int j=1;j<=deg[r];j++)
t+=min(edge[r].ver[j][1],dfs(edge[r].ver[j][0]));
cout<<t<<endl;
}
}
1003 hdu Code Management System
纯模拟
1004 hdu 3660 Alice and Bob's Trip
哈尔滨现场赛题目
#include <stdio.h>
#include<queue>
#include <string.h>
using namespace std;
int INF=0xfffffff;
#define MAXN 501000
int Result[MAXN];
int Sum[MAXN];
int H[MAXN];
int Value[MAXN];
bool V[MAXN];
int Gra[MAXN];
int Queue[MAXN];
struct Node
{
int e;
int next;
};
Node Edge[1000000];
int KK;//edge counter
int N,L,R;
int MIN,MAX;
void BSF()
{
int k1,k2;
int i,j;
int x,e,s;
k1=0; k2=1;
Queue[0]=0;
while(k1<k2)
{
x=Queue[k1];
k1++;
i=Gra[x];
while(i!=-1)
{
e=Edge[i].e;
Queue[k2]=e; k2++;
Sum[e]=Sum[x]+Value[e];
H[e]=1-H[x];
i=Edge[i].next;
}
}
for(i=k2-1;i>=0;i--)
{
e=Queue[i];
if(Gra[e]==-1)
{
if(Sum[e]<L||Sum[e]>R) V[e]=false;
else Result[e]=Value[e];
continue;
}
MIN=INF; MAX=-INF;
j=Gra[e];
while(j!=-1)
{
s=Edge[j].e;
if(!V[s]) {j=Edge[j].next; continue;}
if(Result[s]<MIN) MIN=Result[s];
if(Result[s]>MAX) MAX=Result[s];
j=Edge[j].next;
}
if(MAX+INF==0&&MIN==INF) V[e]=false;
else
{
if(H[e]) Result[e]=MIN+Value[e];
else Result[e]=MAX+Value[e];
}
}
}
int GetInt()
{
int s=0;
char c;
while(c=getchar())
{
if(c<'0'||c>'9') return s;
s=s*10+c-'0';
}
return 0;
}
int main()
{
int a,b,x;
int i;
char c;
while(scanf("%d%d%d",&N,&L,&R)!=EOF)
{
c=getchar();
KK=0;
H[0]=0;
Sum[0]=0;
Value[0]=0;
memset(Gra,-1,sizeof(int)*N);
for(i=1;i<N;i++)
{
//input a,b,c
a=GetInt();
b=GetInt();
x=GetInt();
//KK means the number of edges
//use Edge to record edge
Edge[KK].e=b;
Edge[KK].next=Gra[a];
Gra[a]=KK;
KK++;
Value[b]=x;
}
memset(V,true,sizeof(bool)*N);
BSF();
if(!V[0]||Result[0]<L||Result[0]>R)
printf("Oh, my god!/n");
else
printf("%d/n",Result[0]);
}
return 0;
}
1005 hdu 2768 Cat vs. Dog
最大二分匹配
#include<iostream> #include<string> using namespace std; #define N 510 int troop[N][N],match[N]; int flag[N]; int n,m,ans; char s1[5],s2[5]; struct TYPE { string cid,did; }cat[N],dog[N]; int dfs(int t) { int i; for(i=0;i<=m;i++) { if(flag[i]==0&&troop[t][i]==1) { flag[i]=1; if(match[i]==-1||dfs(match[i])) { match[i]=t; return 1; } } } return 0; } int main() { int i,j,k,t,cas; scanf("%d",&cas); while(cas--) { scanf("%d%d",&n,&m); memset(match,-1,sizeof(match)); memset(troop,0,sizeof(troop)); ans=0; int cx=0,dx=0;//represent num of cat supporter and dog supporter scanf("%d",&k); for(i=0;i<k;i++) { scanf("%s%s",s1,s2); if(s1[0]=='C') { cx++; cat[cx].cid=s1; cat[cx].did=s2; } else { dx++; dog[dx].did=s1; dog[dx].cid=s2; } } for(i=1;i<=cx;i++) { for(j=1;j<=dx;j++) { if(cat[i].cid==dog[j].cid||cat[i].did==dog[j].did) troop[i][j]=1; } } n=cx,m=dx; for(i=0;i<=n;i++)//consider every region for every troop { memset(flag,0,sizeof(flag)); if(dfs(i)) ans++; } cout<<k-ans<<endl; } return 0; }
1006 hdu 2779 Party Party Party
难度:2星
思路:贪心
每次找出结束当前时间下可以参加的结束时间最早的一个item,test whether it can be attended
#include<iostream>
#include<algorithm>
#include<functional>
#include<queue>
using namespace std;
bool flag[50];
struct time
{
int start;
int end;
bool operator <(const time a)const
{
if(a.end==end)
return a.start<start;
return a.end<end;
}
}now,temp;
int main()
{
priority_queue<time>Q;
int i,n,j=0,t;
while(++j)
{
memset(flag,false,sizeof(flag));
scanf("%d",&n);
if(!n)
return 0;
for(i=0;i<n;i++)
{
scanf("%d%d",&now.start,&now.end);
now.start*=2,now.end*=2;//transmit 24 hours to 48*0.5hours
Q.push(now);
}
now.start=now.end=8*2;//because "The earliest a party can start is 8 AM (8) "
int count=0;
while(!Q.empty())
{
temp=Q.top();
Q.pop();
for(t=temp.start;t<=temp.end-1;t++)
if(flag[t]==false)
{
now.start=max(t,now.start+1);
flag[t]=true;
count++;
break;
}
}
printf("On day %d Emma can attend as many as %d parties./n",j,count);
}
}
1007 hdu 2753 Exact Change
最基础的0-1背包,即使不知道背包也可以用DP做
难度:1星
#include<iostream>
using namespace std;
#define N 100
#define M 20010
struct Status
{
bool reach;
int number;
}dp[M];
int v[N];
int main()
{
int cas,i,j,T,money;
while(scanf("%d",&T)!=EOF)
{
while(T--)
{
scanf("%d",&money);
for(i=0;i<=money+10000;i++)
dp[i].reach=false,dp[i].number=N;
dp[0].reach=true,dp[0].number=0;
scanf("%d",&cas);
for(i=0;i<cas;i++)
{
scanf("%d",&v[i]);
for(j=money+10000;j>=v[i];j--)
{
if(dp[j-v[i]].reach)
{
dp[j].reach=true;
dp[j].number=min(dp[j].number,dp[j-v[i]].number+1);
}
}
}
for(i=money;i<=money+10000;i++)
{
if(dp[i].reach)
{
printf("%d %d/n",i,dp[i].number);
break;
}
}
}
}
}
1008 hdu 3685 Rotational Painting
杭州地区赛的一道几何题
难度:4星
思路:
任何一个状态,肯定由两个点连成的一条边在支撑的,分析可知起作用的点是该多边形的凸包。若该多边形的重心到凸包上的这条边做的垂线在这条边上,则能站稳。
剩下的就是套几何模板了。
#include <iostream> #include<algorithm> #include<math.h> #define maxn 50008 using namespace std; #define eps 1e-8 #define zero(x) (((x)>0?(x):-(x))<eps) struct point {double x, y;}; struct line {point a,b;}; point p[maxn],tp[maxn]; bool mult(point sp, point ep, point op) { return (sp.x - op.x) * (ep.y - op.y) >= (ep.x - op.x) * (sp.y - op.y);} bool operator < (const point &l, const point &r) { return l.y < r.y || (l.y == r.y && l.x < r.x);} double xmulti(point p1,point p2,point p0) { return((p1.x-p0.x) * (p2.y-p0.y) -(p2.x-p0.x) * (p1.y-p0.y));} double dis(point p1,point p2){ return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); } point intersection(line u,line v){ point ret=u.a; double t=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x)) /((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x)); ret.x+=(u.b.x-u.a.x)*t; ret.y+=(u.b.y-u.a.y)*t; return ret; } point bcenter(point pnt[], int n){ point p, s; double tp, area = 0, tpx = 0, tpy = 0; p.x = pnt[0].x; p.y = pnt[0].y; for (int i = 1; i <= n; ++i) { // point: 0 ~ n-1 s.x = pnt[(i == n) ? 0 : i].x; s.y = pnt[(i == n) ? 0 : i].y; tp = (p.x * s.y - s.x * p.y); area += tp / 2; tpx += (p.x + s.x) * tp; tpy += (p.y + s.y) * tp; p.x = s.x; p.y = s.y; } s.x = tpx / (6 * area); s.y = tpy / (6 * area); return s; } //graham算法顺时针构造凸包,不包含共线点,O(nlogn) int graham(point pnt[], int n, point res[]){ int i, len, k = 0, top = 1; sort(pnt, pnt + n); if (n == 0) return 0; res[0] = pnt[0]; if (n == 1) return 1; res[1] = pnt[1]; if (n == 2) return 2; res[2] = pnt[2]; for (i = 2; i < n; i++) { while (top && mult(pnt[i], res[top], res[top-1])) top--; res[++top] = pnt[i]; } len = top; res[++top] = pnt[n - 2]; for (i = n - 3; i >= 0; i--) { while (top!=len && mult(pnt[i], res[top], res[top-1])) top--; res[++top] = pnt[i]; } return top; // 返回凸包中点的个数 } point ptoseg(point p,point l1,point l2) { point t=p; t.x+=l1.y-l2.y,t.y+=l2.x-l1.x; if (mult(l1,t,p)*mult(l2,t,p)>eps) { if(dis(p,l1)<dis(p,l2)) return l1; return l2; } line A,B; A.a=p,A.b=t; B.a=l1,B.b=l2; // return intersection(p,t,l1,l2); return intersection(A,B); } int ponls(line l,point p) {return( fabs(xmulti(l.b,p,l.a))<=eps &&( ((p.x-l.a.x)*(p.x-l.b.x)<0 ) ||((p.y-l.a.y)*(p.y-l.b.y)<0 )) );} int main() { int t, n; int i; scanf("%d", &t); while (t--) { scanf("%d", &n); for (i = 0; i < n; ++i) scanf("%lf%lf", &p[i].x, &p[i].y); point gravity = bcenter(p,n); int tnum=0; tnum=graham(p,n,tp);//凸包的点顺时针顺序存于tp point p1,p2,temp; line ll; int count=0; for(i=0;i<tnum;i++) { p1=tp[i];p2=tp[i+1]; ll.a=p1;ll.b=p2; point tt=ptoseg(gravity,p1,p2); if(ponls(ll,tt)) count++; } printf("%d/n",count); } return 0; }