Tyvj P2079(Spfa)

P2079 - 防御机制

From tangjz    Normal (OI)
总时限:10s    内存限制:128MB    代码长度限制:64KB

背景 Background

NOIp2012考后欢乐赛第三题

描述 Description

  服务器的新防御系统快要建好了,但是当正在数据库升级的时候,突然有黑客入侵机房网络,但是就在那时,插网线的房间钥匙丢了。所以Admin开始做防御机房的工作。
  不过,由于访问某台电脑可经过其他电脑加速,但是不能访问途经电脑,而且单位时间内一台电脑只能发出一条指令,指令不含嵌套指令,Admin只能一台一台的建立防御,幸好如此,黑客也是一台一台入侵,不过二人都会选择最优方案进行操作。所以Admin在主控端(教师端)不停的巡察各台电脑的同时,要求你在简短的时间内帮Admin计算一下哪些电脑将必然被入侵成功,以便于Admin及时做出额外的保护措施,如果所有可能被入侵的电脑都能被保护,那么请计算出将所有连接在主控端上的电脑做好防御所需的总时间。
  注意:只有黑客的入侵时间短于Admin的防御时间,黑客才能成功入侵。

输入格式 InputFormat

第一行为两个正整数N,M,表示有N台电脑,M条网线。(黑客近似地看为第N台电脑,在机房外)
第二行为N-2个正整数,表示每台电脑的访问时间t。
第三行到第 M+2 行,每行三个整数u,v,w,表示电脑u和v之间有一条网线,使用该网线互相到达对方电脑需要w个单位时间。

输出格式 OutputFormat

输出共两行。
如果有可能会防御失败的电脑,第一行输出"No",第二行升序输出这些电脑的编号(空格隔开)。
否则第一行输出"Yes",第二行输出将所有连接在主服务器上的电脑做好防御所需的总时间。

样例输入 SampleInput [复制数据]

[Sample 1]
4 6
1 2
1 2 10
1 3 5
1 4 1
2 3 4
2 4 1
3 4 10

[Sample 2]
5 7
1 1 1
1 2 70
1 3 70
1 4 70
1 5 70
2 5 70
3 5 70
4 5 70

样例输出 SampleOutput [复制数据]

[Sample 1]
No
2

[Sample 2]
Yes
213

数据范围和注释 Hint

样例解释:
第一组:由于1->2:2,4->2:1,所以2号电脑会被入侵成功
第二组:1到2,3,4点的时间均为71,5到2,3,4点的时间均为71,防御成功

对于20% 的数据,1 <=  N  <= 1000 ,1 <=  M  <= 2000
对于60% 的数据,1 <=  N  <= 5000 ,1 <=  M  <= 100000
对于100%的数据,1 <=  N  <= 10000,1 <=  M  <= 200000
对于100%的数据,1 <= t,w <= 10000,1 <= u,v <= N
提示:由于学生贪玩,有可能某个电脑没有连接主机,却接入网络;当然也有部分同学上课被禁网了。

时间限制 TimeLimitation

1s

来源 Source

tjz

这题就是Spfa.


Program defence;
const
   maxn=90000;
   maxm=500000;
   inf=2139062143;
type
   dis_arr=record
              s:longint;
              d:array[1..maxn] of longint;
           end;
var
   n,m,i,j:longint;
   w:array[1..maxn] of longint;
   head,edge,next,weight:array[1..maxm] of longint;
   size:longint;
   d1,d2:dis_arr;
   queue:array[1..6000000] of longint;

Procedure addedge(u,v,w:longint);
begin
   inc(size);
   edge[size]:=v;
   weight[size]:=w;
   next[size]:=head[u];
   head[u]:=size;
end;
Procedure addedge_main;
var
   u,v,w:longint;
begin
   read(u,v,w);
   addedge(u,v,w);addedge(v,u,w);
end;
Procedure spfa(var d:dis_arr);
var
   i,j,now,p:longint;
begin
   i:=1;j:=1;queue[1]:=d.s;
   fillchar(d.d,sizeof(d.d),127);d.d[d.s]:=0;
   while (i<=j) do
   begin
      now:=queue[i];
      p:=head[now];
      while (p<>0) do
      begin
         if (d.d[now]+weight[p]<d.d[edge[p]]) then
         begin
            inc(j);
            queue[j]:=edge[p];
            d.d[edge[p]]:=d.d[now]+weight[p];
         end;
         p:=next[p];
      end;
      inc(i);
   end;
end;
Procedure print;
var
   i,j:longint;
   ans:int64;
   flag:boolean;
begin
   flag:=false;    ans:=0;
   for i:=2 to n-1 do
   begin
      if d1.d[i]<>inf then ans:=ans+int64(w[i]+d1.d[i]);
      if (d1.d[i]>d2.d[i]) then
      begin
         if not(flag) then begin flag:=true; writeln('No'); end
         else write(' ');
         write(i);
      end;
   end;
   if not(flag) then
   begin
      writeln('Yes');
      writeln(ans);
   end
   else writeln;
end;
begin
//   assign(input,'defence.in');
//   reset(input);
   fillchar(head,sizeof(head),0);
   fillchar(edge,sizeof(edge),0);
   fillchar(next,sizeof(next),0);
   size:=0;
   read(n,m); d1.s:=1;d2.s:=n;
   for i:=2 to n-1 do read(w[i]);
   for i:=1 to m do
   begin
      addedge_main;
   end;
   spfa(d1);spfa(d2);
   print;
end.

HDU 3265(矩形面积并-分割矩形)

Posters

Problem Description
有很多海报,每个海报都被减去了一个矩形(可能全减),现在给出没张海报的位置,求它们的面积并。
保证坐标在(0, 0)到(50000, 50000)之间。没有海报斜着贴,减去的矩形边与x,y轴平行。
 
Input
有很多数据。
对于每组数据第一行有一个整数N (0<N<=50000)表示海报数 接下来n行,每行8个整数 x1, y1, x2, y2, x3, y3, x4, y4, 表示每张海报的左下角坐标(x1, y1),右上角坐标(x2, y2) ,减去的矩形左上角坐标(x3, y3),右上角坐标(x4, y4)(0<=xi, yi<=50000(i=1…4) and x1<=x3<x4<=x2, y1<=y3<y4<=y2).

数据以0结尾。
 


Output
对于每组数据输出一行,表示它们的面积并。
 


Sample Input
2 0 0 10 10 1 1 9 9 2 2 8 8 3 3 7 7 0
 


Sample Output
56
 

这题就是要把矩形差分成如下形式:



然后进行矩形面积并:

谨记问题转化后各数组的大小。


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<cctype>
#include<iostream>
#include<functional>
#include<algorithm>
using namespace std;
#define MAXN (50000+10)
#define MAXT (MAXN*5)
#define MAXXi (50000+10)
#define Lson (x<<1)
#define Rson ((x<<1)^1)
int hpos[MAXN];
int x[MAXN*4]={0};
struct SegMent
{
    int x1,x2,h,type;
    SegMent(){}
    SegMent(int _x1,int _x2,int _h,int _type):x1(_x1),x2(_x2),h(_h),type(_type){}
    friend bool operator<(const SegMent a,const SegMent b){return a.h<b.h;}
};
int n,size;
struct SegMent_array
{
    SegMent a[MAXN*8];
    int size;
    SegMent_array():size(0)
    {
        memset(a,0,sizeof(a));
    }

    bool add(int x1,int x2,int y1,int y2)
    {
        if (x1==x2||y1==y2) return 0;
        else
        {
            a[++size]=SegMent(x1,x2,y1,1);
            a[++size]=SegMent(x1,x2,y2,-1);
            return 1;
        }
    }
}a;
struct SegMentTree
{
    long long sum[MAXT],cnt[MAXT],len[MAXT];
    int M,n;
    void fillchar(int _n)
    {
        n=_n;
        M=1;while (M-2<n) M<<=1;
        memset(sum,0,sizeof(sum));
        memset(cnt,0,sizeof(cnt));
        memset(len,0,sizeof(len));
        for (int i=M+1;i<=M+n;i++) len[i]=x[i-M+1]-x[i-M];
        for (int i=M-1;i>=1;i--) len[i]=len[i<<1]+len[(i<<1)^1];
    }
    void pushup(int x)
    {
		sum[x]=(cnt[x])?(len[x]):((x<M)?(sum[Lson]+sum[Rson]):0);
	}
	void update(int x)
	{
		while (x)
		{
			pushup(x);x>>=1;
		}
	}
    void insert(int l,int r,long long c)
	{
		if (l>r) return ;
		l=l-1+M;r=r+1+M;
		int ll=l,rr=r;
		for (;l^r^1;l>>=1,r>>=1)
		{
			if (~l&1) {cnt[l+1]+=c; pushup(l+1);}
			if (r&1) {cnt[r-1]+=c; pushup(r-1);}
		}
//		cout<<endl<<"Push:"<<ll<<' '<<rr<<endl;
		update(ll);update(rr);
	}
	void print()
	{
		for (int i=1;i<=2*M;i++) if (sum[i]) cout<<i<<':'<<sum[i]<<' ';
		cout<<endl;
		for (int i=1;i<=2*M;i++) if (cnt[i]) cout<<i<<':'<<cnt[i]<<' ';
		cout<<endl;
		cout<<endl;
	}
}t;


int main()
{
//  freopen("Hdu3265.in","r",stdin);
    while (scanf("%d",&n)!=EOF)
    {
		if (n==0) break;
	    for (int i=1;i<=n;i++)
    	{
        	int x1,y1,x2,y2,x3,y3,x4,y4;
	        scanf("%d%d%d%d%d%d%d%d",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4);
    	    a.add(x1,x3,y1,y4);
        	a.add(x3,x2,y1,y3);
	        a.add(x1,x4,y4,y2);
    	    a.add(x4,x2,y3,y2);
			x[i*4-3]=x1;x[i*4-2]=x2;x[i*4-1]=x3;x[i*4]=x4;
	    }
    	sort(x+1,x+4*n+1);
    	size=unique(x+1,x+4*n+1)-(x+1);
/* 		for (int i=1;i<=size;i++) cout<<x[i]<<' ';
    	cout<<endl;
*/
//		cout<<size;
    	for (int i=1;i<=size;i++) hpos[x[i]]=i;
		t.fillchar(size-1);

		sort(a.a+1,a.a+1+a.size);
//		cout<<'s';
//		for (int i=1;i<=a.size;i++) cout<<a.a[i].x1<<' '<<a.a[i].x2<<' '<<a.a[i].h<<' '<<a.a[i].type<<endl;
		long long ans=0;
		for (int i=1;i<=a.size;i++)
		{
			ans+=t.sum[1]*((long long)a.a[i].h-a.a[i-1].h);
			t.insert(hpos[a.a[i].x1],hpos[a.a[i].x2]-1,a.a[i].type);
/*			cout<<a.a[i].x1<<' '<<a.a[i].x2<<' '<<a.a[i].h<<' '<<a.a[i].type<<endl;
			cout<<ans<<endl;
			t.print();
*/		}
		cout<<ans<<endl;
		a.size=0;
	}
	return 0;
}