标签:
题目描述对于 100%的数据 的数据 ,1 ≤ N, M, T ≤ 100000,1 ≤ a, b ≤ N,a≠b,要求输出的 要求输出的 要求输出的 P<=N+M+T。
首先这题第一步肯定是给m的要求直接连上有向边,感性上来说。它对第二种操作的影响会比较小。然后就是快速求有向图的连通性。然而似乎并没有什么低于n^2的做法。。。(事后好像标算不过是压了个位)。然后为了避免爆内存分了个块。。。也是有点玄学。
然而我显然不认为n^2是可以过得。。。于是我就写了个非常玄学的记忆化时间空间复杂度都非常深不可测。。。。第4个点跑了1.5秒。第五个点跑了5秒,第6个点144秒。。。然而这三个点大小其实差不多。。。其他点(包括数据更大的)都在1秒以内了。。。看上去似乎超出了我乱搞的预期。
但是我一开始却爆0了。。。因为多组数据是个坑啊。。。一般人做到no的时候就直接break了。。。然后继续读数据就会混乱掉。。。日狗。。。
#include <cstdio>
#include <cmath>
#include <ctime>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include<map>
#include<list>
#define pb push_back
#define lb lower_bound
#define sqr(x) (x)*(x)
#define lowbit(x) (x)&(-x)
#define Abs(x) ((x) > 0 ? (x) : (-(x)))
#define forup(i,a,b) for(int i=(a);i<=(b);i++)
#define fordown(i,a,b) for(int i=(a);i>=(b);i--)
#define ls(a,b) (((a)+(b)) << 1)
#define rs(a,b) (((a)+(b)) >> 1)
#define getlc(a) ch[(a)][0]
#define getrc(a) ch[(a)][1]
#define maxn 100005
#define maxm 100005
#define INF 1070000000
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
template<class T> inline
void read(T& num){
num = 0; bool f = true;char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') f = false;ch = getchar();}
while(ch >= '0' && ch <= '9') {num = num * 10 + ch - '0';ch = getchar();}
num = f ? num: -num;
}
int out[100];
template<class T> inline
void write(T x,char ch){
if (x==0) {putchar('0'); putchar(ch); return;}
if (x<0) {putchar('-'); x=-x;}
int num=0;
while (x){ out[num++]=(x%10); x=x/10;}
fordown(i,num-1,0) putchar(out[i]+'0'); putchar(ch);
}
/*==================split line==================*/
int n,m,t;
map<int,bool> f[maxn];
vector<int> g1[maxn],g2[maxn];
vector<int> s;
vector<int> G[maxn];
int cnt=0;
bool vis[maxn];
int id[maxn];
void dfs1(int x)
{ vis[x]=1;
for(int i=0;i<g1[x].size();i++)
{ int v=g1[x][i];
if(!vis[v])
{ dfs1(v);}
}
s.pb(x);
}
void dfs2(int x)
{ id[x]=cnt;
for(int i=0;i<g2[x].size();i++)
{ int v=g2[x][i];
if(!id[v])
dfs2(v);
}
}
bool work(int x,int y)
{ if(f[x].count(y)!=0)
{ return f[x][y];}
for(int i=0;i<G[x].size();i++)
{ int v=G[x][i];
f[x][y]=work(v,y);
if(f[x][y]==true) return true;
}
return false;
}
void clearall()
{ forup(i,1,n)
{f[i].clear(); g1[i].clear();g2[i].clear();}
forup(i,1,cnt) G[i].clear();
s.clear();
}
int main()
{ freopen("gplt.in","r",stdin);
freopen("gplt.out","w",stdout);
while(scanf("%d%d",&n,&m)!=EOF)
{ cnt=0; clearall();
forup(i,1,m)
{ int x,y; read(x);read(y);
g1[x].pb(y);g2[y].pb(x);
}
memset(vis,0,sizeof(vis));
forup(i,1,n)
{ if(!vis[i])
dfs1(i);
}
for(int i=s.size()-1;i>=0;i--)
{ int v=s[i];
if(!id[v])
{cnt++; dfs2(v);}
}
forup(i,1,n)
for(int j=0;j<g1[i].size();j++)
{ int v=g1[i][j];
f[id[i]][id[v]]=1;
}
forup(i,1,cnt)
for(map<int,bool>::iterator j=f[i].begin();j!=f[i].end();j++)
{int v=j->first;G[i].pb(v);}
read(t);
bool flag=1;
forup(i,1,t)
{ int x,y;read(x);read(y);
if(flag==0) continue;
if(id[x]==id[y])
{ flag=0;printf("NO\n");
continue;
}
bool ans=work(id[x],id[y]);
if(ans) {flag=0;printf("NO\n");continue;}
}
if(flag==1)
{printf("YES\n");
write(m,'\n');
forup(x,1,n)
for(int y=0;y<g1[x].size();y++)
{ int v=g1[x][y];
write(x,' ');write(v,'\n');
}
}
}
return 0;
}
标签:
原文地址:http://blog.csdn.net/qq_22036225/article/details/51939375