[SCOI2003]蜘蛛难题

时间:2023-03-08 23:58:27
[SCOI2003]蜘蛛难题

题目

对于当年来说似乎是神题??

做法

对于联通注水来说,我们考虑把所有能平分到水的桶同时加高度,然后暴力判断

My complete code

copy来的代码

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=105;
const int INF=32083208;
struct edge {int x,y,next;} b[N];
struct point {int x,y,h;} c[N],pos;
int n,m,a[N],tot,ans,q[N]; bool v[N];
inline long long getint()
{
long long x=0; char c=getchar(); bool flag=false;
while ((c!='-')&&((c<'0')||(c>'9'))) c=getchar();
if (c=='-') flag=true,c=getchar();
while ((c>='0')&&(c<='9')) x=x*10+(long long)(c-'0'),c=getchar();
if (flag) return -x; else return x;
}
inline int find(int x)
{
for (int i=1; i<=n; i++) if (x==c[i].x) return i;
return 0;
}
inline void addedge(int x,int y,int z)
{
++tot; b[tot].x=y; b[tot].y=z; b[tot].next=a[x]; a[x]=tot;
++tot; b[tot].x=x; b[tot].y=z; b[tot].next=a[y]; a[y]=tot;
}
void init()
{
n=getint(); ans=0; tot=0; memset(a,0,sizeof(a));
for (int i=1; i<=n; i++) c[i].x=getint(),c[i].y=getint(),c[i].h=c[i].y+getint(); m=getint();
for (int i=1; i<=m; i++)
{
int x=getint(),y=getint(),d=getint();
addedge(find(x-1),find(x+d),y);
}
pos.x=getint(); pos.y=getint();
}
void bfs()
{
int head=0,tail=0;
for (int i=1; i<=n; i++) if (v[i]) q[++tail]=i;
while (head<tail)
{
int k=q[++head];
for (int p=a[k];p;p=b[p].next)
{
int pp=b[p].x; if (v[pp]) continue;
if (c[k].h<=b[p].y) v[pp]=true,q[++tail]=pp;
}
}
}
void solve()
{
memset(v,false,sizeof(v)); v[1]=true;
while (true)
{
bfs(); int maxh=-INF;
for (int i=1; i<=n; i++) if (v[i]) maxh=max(maxh,c[i].h);
if ((v[pos.x])&&(c[pos.x].h==maxh)&&(c[pos.x].h==pos.y)) {printf("%d\n",ans); return;}
for (int i=1; i<=n; i++) if ((v[i])&&(c[i].h==maxh)&&(c[i].h==c[i].y)) {printf("-1\n"); return;}
for (int i=1; i<=n; i++) if ((v[i])&&(c[i].h==maxh)) c[i].h--,ans++;
}
}
int main()
{
init();
solve();
return 0;
}