As a good (e), (xin) of small purple question, it is worth doing (though subject nonsense, and practice nausea)
Title Description
In broad African desert, living with a group of industrious and brave alpaca family. Christine tribe is known as the "prophet" of Alpaca L. Sotomon is the leader of the family, outsiders also referred to as "the camel door king." The camel door King devoted his life to maintain stability and harmony of the family, he had personally led his army crushed crab brutal aggression of imperialism, for the tribe set hehe exploits. The camel door Wang Yisheng countless treasures, but because of its low-key frugal nature, he will treasure buried in the underground palace's own design, which is the starting point for today Henry Curtis story. Henry is a money-grubber greedy guy, and very smart, he took great pains to plan the theft of this action to crack heavy organs came to the front of this underground palace.
Whole palace in a matrix form, between the R × C rectangular palace, where there are N buried hidden treasures between palace, palace called treasure. Palace, the inter-entity palace by rigid walls adjacent to the barrier by a palace to the other only through the inter-gate king original camel moves - Portal. The camel is the king of the N door between each room a treasure palace erected a portal, is not no treasure palace portal, all portals of the palace is divided into three:
-
"Days horizontal door": the gate of a palace may be transmitted to any counterparts;
-
"Atlas vertical door": the door can be transmitted to any of the palace a same column;
-
"Any door": a door may be transmitted to the gate located in the center of a house for around 8 grid of any one palace (palace target if present).
Henry, of course thoughtful in advance to get the door of the king palace camel tender book of the year, the books detailed record of every fan portal belongs to the palace and type. Moreover, although apart inside and outside the palace, but he was ready to own a portable portal, it can be transferred to their own hall at any one palace treasure hunt beginning and the end of any transfer out of the palace a palace. Xu whole palace out only once, and portable door can not be transferred between the palace. Fortunately, however, the use of indoor Palace Portal There is no limit, each palace can make multiple entries.
Henry has now opened the door portability, choose a house that is about to enter. To do more to get the treasure, he hoped to arrange a route through the palace different treasure as much as possible. Please tell Henry that route passing through the largest number of different treasure palace.
Input Format
The first row gives the input file sotomon.in three positive integer N, R, C.
The following N rows, each row gives an information portal, comprising three positive integers xi, yi, of Ti, indicating that the transfer gate provided in the first row located at xi and yi treasure palace column type is Ti. Ti is an integer of 1 to 3, and 1 represents may be transmitted to the second xi row of any one of the "cross-day door", 2 represents transferred to the "vertical atlas door" arbitrary row yi-column, 3 represents around can be transmitted to 8 grid palace of "any door."
Ensure 1≤xi≤R, 1≤yi≤C, all portal position different from each other.
Output Format
Output file sotomon.out only a positive integer representing the maximum number of different treasure palace determine your route passes.
Sample input and output
10 7 7 2 2 1 2 4 2 1 7 2 2 7 3 4 2 2 4 4 1 6 7 3 7 7 1 7 5 2 5 2 1
9
Description / Tips
Data scale and conventions:
--------------------------------------------split line---- -------------------------------------------
At first glance, ordinary title search, thinking fifty-six very easy to get, and then like a pruning shears
But this extremely disgusting to see the range of data, 10 ^ 6, a matrix can save any
Made, a simple tarjan + DP
But think about the connection side seems a bit much
Then we can optimize (point which is also the most difficult subject, I tune a night) the construction side
Since then the particularity of each door, we should build a separate drawing, which is three algorithms for cross Tianmen each line, we will build it into a ring for each vertical column atlas door, and we will build it into a ring. Because we know:
All doors days between each horizontal row to each other are certainly accessible, and among all the doors of each column atlas longitudinal certainly are mutually accessible. So we can say:
When you reach a cross day door of a row when you reach this line all cross Tianmen, when you reach a vertical atlas door for a column when you reach this column all vertical atlas door.
So we can build it into a ring. The use of Tarjan came. We can use these two Tarjan ring shrunk to the point. For any door I did not expect violence to build than the side a better way, so he built violent side friends ~ ~ ~.
But if that was not enough, we have
SORT
We naturally hope to find a day cross the door when the sooner the better, so try to cross the sky in front of the door, so cmp is as follows:
bool cmp1(node a,node b){ if(a.x!=b.x)return a.x<b.x; if(a.opt==1)return 1; if(b.opt==1)return 0; return a.y<b.y; }
So look for the door when the vertical atlas, too:
bool cmp2(node a,node b){ if(a.y!=b.y)return a.y<b.y; if(a.opt==2)return 1; if(b.opt==2)return 0; return a.x<b.x; }
Well, we have lined up order, the next step is even clever side, we have the first represents the first time each cycle to find, last represented on a
So, even side code:
sort(P+1,P+number+1,cmp1); first=last=1; for(int i=1;i<=number;i++){ if(P[i].x!=P[i+1].x){ if(first!=last)add(P[last].id,P[first].id); first=last=i+1; } else{ if(P[last].opt==1)add(P[last].id,P[i+1].id); if(P[i+1].opt==1)last=i+1; if(P[first].opt!=1)last=first=i+1; } }
Vertical door too atlas
So the next step is any door (think of A Dream), which we use to store map
Of course, this is the players enjoy c ++, other languages can use hash
Then the code is as follows:
for(int i=1;i<=number;i++){ if(P[i].opt==3){ for(int k=0;k<8;k++){ int nx=P[i].x+dx[k],ny=P[i].y+dy[k]; if(fh.count(pa(nx,ny))) add(P[i].id,fh[pa(nx,ny)]); } } }
Well, the end of the construction side of the poor, then look for the ring with Tarjan
这个不用多说,直接上代码:
void Tarjan(int now){ low[now]=dfn[now]=++deeth;res[now]=1; q[++top]=now; for(int i=head[now];i;i=nxt[i]){ int y=ver[i]; if(!dfn[y])Tarjan(y),low[now]=min(low[now],low[y]); else if(res[y])low[now]=min(low[now],dfn[y]); } if(dfn[now]==low[now]){ color[now]=++sum;res[now]=0; while(q[top]!=now){ size[sum]++; res[q[top]]=0;color[q[top--]]=sum; } size[sum]++;top--; } }
那么最后就是一个简单的DP了:
void dfs(int now,int fa){ if(dp[now]>size[now])return; dp[now]=size[now]; for(int i=head1[now];i;i=nxt1[i]){ int y=ver1[i]; if(y==fa)continue; dfs(y,now); dp[now]=max(dp[now],dp[y]+size[now]); } } for(int i=1;i<=sum;i++){ if(in[i]==0){ dfs(i,0);ans=max(ans,dp[i]); } }
那么AC代码就是:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define pa pair<int,int> 4 5 const int _=300002; 6 int number,length,wide,first,last,size[_],dp[_],in[_]; 7 int ver[_*10],head[_*10],nxt[_*10],from[_*10],tot,ans=-1; 8 int ver1[_*10],head1[_*10],nxt1[_*10],tot1; 9 int dx[9]={-1,-1,-1,0,0,1,1,1},dy[9]={-1,0,1,-1,1,-1,0,1}; 10 int color[_],sum,low[_],dfn[_],q[_],top,deeth,res[_]; 11 struct node{int x,y,opt,id;}P[_]; 12 map<pa,int>fh; 13 14 int read(){ 15 int s=0,w=1;char ch=getchar(); 16 while(ch<'0'||ch>'9')w=(ch=='-')?-1:1,ch=getchar(); 17 while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar(); 18 return s*w; 19 } 20 21 void add(int x,int y){ 22 from[++tot]=x;ver[tot]=y;nxt[tot]=head[x];head[x]=tot; 23 } 24 25 void ad(int x,int y){ 26 ver1[++tot1]=y;nxt1[tot1]=head1[x];head1[x]=tot1; 27 } 28 29 bool cmp1(node a,node b){ 30 if(a.x!=b.x)return a.x<b.x; 31 if(a.opt==1)return 1; 32 if(b.opt==1)return 0; 33 return a.y<b.y; 34 } 35 36 bool cmp2(node a,node b){ 37 if(a.y!=b.y)return a.y<b.y; 38 if(a.opt==2)return 1; 39 if(b.opt==2)return 0; 40 return a.x<b.x; 41 } 42 43 void Tarjan(int now){ 44 low[now]=dfn[now]=++deeth;res[now]=1; 45 q[++top]=now; 46 for(int i=head[now];i;i=nxt[i]){ 47 int y=ver[i]; 48 if(!dfn[y])Tarjan(y),low[now]=min(low[now],low[y]); 49 else if(res[y])low[now]=min(low[now],dfn[y]); 50 } 51 if(dfn[now]==low[now]){ 52 color[now]=++sum;res[now]=0; 53 while(q[top]!=now){ 54 size[sum]++; 55 res[q[top]]=0;color[q[top--]]=sum; 56 } 57 size[sum]++;top--; 58 } 59 } 60 61 void dfs(int now,int fa){ 62 if(dp[now]>size[now])return; 63 dp[now]=size[now]; 64 for(int i=head1[now];i;i=nxt1[i]){ 65 int y=ver1[i]; 66 if(y==fa)continue; 67 dfs(y,now); 68 dp[now]=max(dp[now],dp[y]+size[now]); 69 } 70 } 71 72 int main(){ 73 // freopen("precious.in","r",stdin); 74 // freopen("precious.out","w",stdout); 75 number=read();length=read();wide=read(); 76 for(int i=1;i<=number;i++){ 77 P[i].x=read();P[i].y=read();P[i].opt=read();P[i].id=i; 78 fh[pa(P[i].x,P[i].y)]=i; 79 } 80 //----------------------------------------------------- 81 for(int i=1;i<=number;i++){ 82 if(P[i].opt==3){ 83 for(int k=0;k<8;k++){ 84 int nx=P[i].x+dx[k],ny=P[i].y+dy[k]; 85 if(fh.count(pa(nx,ny))) 86 add(P[i].id,fh[pa(nx,ny)]); 87 } 88 } 89 } 90 //----------------------------------------------------- 91 sort(P+1,P+number+1,cmp1); 92 first=last=1; 93 for(int i=1;i<=number;i++){ 94 if(P[i].x!=P[i+1].x){ 95 if(first!=last)add(P[last].id,P[first].id); 96 first=last=i+1; 97 } 98 else{ 99 if(P[last].opt==1)add(P[last].id,P[i+1].id); 100 if(P[i+1].opt==1)last=i+1; 101 if(P[first].opt!=1)last=first=i+1; 102 } 103 } 104 //------------------------------------------------------ 105 sort(P+1,P+number+1,cmp2); 106 first=last=1; 107 for(int i=1;i<=number;i++){ 108 if(P[i].y!=P[i+1].y){ 109 if(first!=last)add(P[last].id,P[first].id); 110 first=last=i+1; 111 } 112 else{ 113 if(P[last].opt==2)add(P[last].id,P[i+1].id); 114 if(P[i+1].opt==2)last=i+1; 115 if(P[first].opt!=2)last=first=i+1; 116 } 117 } 118 //------------------------------------------------------ 119 for(int i=1;i<=number;i++) 120 if(!dfn[i])Tarjan(i); 121 for(int i=1;i<=tot;i++){ 122 int x=from[i],y=ver[i]; 123 if(color[x]==color[y])continue; 124 ad(color[x],color[y]);in[color[y]]++; 125 } 126 for(int i=1;i<=sum;i++){ 127 if(in[i]==0){ 128 dfs(i,0);ans=max(ans,dp[i]); 129 } 130 } 131 cout<<ans; 132 return 0; 133 }