4.28
P5318 【深基18.例3】查找文献
每个文献看之前一定要看前面的资料,分别用dfs和bfs跑,并且要求路径为字典序,对每个点的路径排序,跑dfs和bfs
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define INT_MINs -2000000000
#define INT_MAXs 1000000001
#define mod 1000000007
#define MID mid=(l+r)/2
#define REP1(i,x,y) for(int i=x;i
#define REP2(i,x,y) for(int i=x;i<=y;i++)
#define ls (2*k)
#define lr (2*k+1)
#define lson l,mid,2*k
#define lron mid+1,r,2*k+1
#define inf 0x3f3f3f3f3f3f3f3f
#define IOS ios::sync_with_stdio(0);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int dx[4]={0,-1,0,1},dy[4]={1,0,-1,0};
bool vis1[100005],vis2[100005];
int n,m;
vector<int>vt[100005];
void dfs(int u)
{
vis1[u]=true;
cout<<u<<' ';
for(int i=0;i<vt[u].size();i++)
{
int v=vt[u][i];
if(!vis1[v])
dfs(v);
}
}
void bfs()
{
queue<int>q;
q.push(1);
vis2[1]=true;
while(!q.empty())
{
int u=q.front();
q.pop();
cout<<u<<' ';
for(int i=0;i<vt[u].size();i++)
{
int v=vt[u][i];
if(!vis2[v])
{
vis2[v]=true;
q.push(v);
}
}
}
}
int main()
{
cin>>n>>m;
for(int i=0;i<m;i++)
{
int u,v;
cin>>u>>v;
vt[u].push_back(v);
}
for(int i=1;i<=n;i++)
sort(vt[i].begin(),vt[i].end());
dfs(1);
cout<<endl;
bfs();
return 0;
}
P3916 图的遍历
对于每个点都打印出他可以走到最大的点
从大往小的跑,每个点的最大值为上个点的最大值的
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define INT_MINs -2000000000
#define INT_MAXs 1000000001
#define mod 1000000007
#define MID mid=(l+r)/2
#define REP1(i,x,y) for(int i=x;i
#define REP2(i,x,y) for(int i=x;i<=y;i++)
#define ls (2*k)
#define lr (2*k+1)
#define lson l,mid,2*k
#define lron mid+1,r,2*k+1
#define inf 0x3f3f3f3f3f3f3f3f
#define IOS ios::sync_with_stdio(0);
#define pb(a) push_back(a)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int dx[4] = { 0,-1,0,1 }, dy[4] = { 1,0,-1,0 };
int n,m,vis[100005];
vector<int>vt[100005];
void dfs(int u,int next)
{
if(vis[u])
return;
vis[u]=next;
for(int i=0;i<vt[u].size();i++)
{
dfs(vt[u][i],next);
}
}
int main()
{
cin>>n>>m;
for(int i=0;i<m;i++)
{
int u,v;
cin>>v>>u;
vt[u].pb(v);
}
for(int i=n;i>0;i--)
{
dfs(i,i);
}
for(int i=1;i<=n;i++)
printf("%d%c",vis[i],i==n?'\n':' ');
return 0;
}
P1113 杂务
要求先做完前面,计算所需最大时间
裸的拓扑排序,每个点的时间为上个点到加上这个点,计算最大值
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define INT_MINs -2000000000
#define INT_MAXs 1000000001
#define mod 1000000007
#define MID mid=(l+r)/2
#define REP1(i,x,y) for(int i=x;i
#define REP2(i,x,y) for(int i=x;i<=y;i++)
#define ls (2*k)
#define lr (2*k+1)
#define lson l,mid,2*k
#define lron mid+1,r,2*k+1
#define inf 0x3f3f3f3f3f3f3f3f
#define IOS ios::sync_with_stdio(0);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int dx[4] = { 0,-1,0,1 }, dy[4] = { 1,0,-1,0 };
struct node {
int v, next;
}num[10000005];
int head[100005], a[100005], n, sum[100005], t[100005];
int cnt =0;
void add(int u, int v)
{
num[++cnt].v = v;
num[cnt].next = head[u];
head[u] = cnt;
}
void tp()
{
queue<int>q;
for (int i = 1; i <= n; i++)
{
if (!a[i])
{
q.push(i);
sum[i] = t[i];
}
}
while (!q.empty())
{
int u = q.front();
q.pop();
for (int i = head[u]; i; i = num[i].next)
{
int v = num[i].v;
a[v]--;
sum[v] = max(sum[v], sum[u] + t[v]);
if (!a[v])
{
q.push(v);
}
}
}
int ans = 0;
for (int i = 1; i <= n; i++)
ans = max(ans, sum[i]);
cout << ans << endl;
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
{
int u, time;
cin >> u >> time;
t[u] = time;
while (1)
{
int k;
cin >> k;
if (!k)
break;
a[u]++;
add(k, u);
}
}
tp();
return 0;
}
P4017 最大食物链计数
共有多少中最长食物链
每个点的数量为加上前面一个点的数量,如果后面没有捕食者了,总数加上这个点
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define INT_MINs -2000000000
#define INT_MAXs 1000000001
#define mod 1000000007
#define MID mid=(l+r)/2
#define REP1(i,x,y) for(int i=x;i
#define REP2(i,x,y) for(int i=x;i<=y;i++)
#define ls (2*k)
#define lr (2*k+1)
#define lson l,mid,2*k
#define lron mid+1,r,2*k+1
#define inf 0x3f3f3f3f3f3f3f3f
#define IOS ios::sync_with_stdio(0);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int dx[4] = { 0,-1,0,1 }, dy[4] = { 1,0,-1,0 };
int head[5005],ans=0,n,m,vis[5005],cnt=0,f[5005];
struct node{
int v,next;
}num[5000005];
void add(int u,int v)
{
num[++cnt].v=v;
num[cnt].next=head[u];
head[u]=cnt;
}
void tp()
{
queue<int>q;
for(int i=1;i<=n;i++)
if(!vis[i])
{
q.push(i);
f[i]=1;
}
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i;i=num[i].next)
{
int v=num[i].v;
f[v]+=f[u];
f[v]%=80112002;
vis[v]--;
if(!vis[v])
{
q.push(v);
if(!head[v])
{
ans+=f[v];
ans%=80112002;
}
}
}
}
cout<<ans;
}
int main()
{
cin>>n>>m;
for(int i=0;i<m;i++)
{
int u,v;
cin>>u>>v;
vis[v]++;
add(u,v);
}
tp();
return 0;
}
P1807 最长路
把每个点取反,就等于最短路,Bellman-Ford算法跑一边
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define INT_MINs -2000000000
#define INT_MAXs 1000000001
#define mod 1000000007
#define MID mid=(l+r)/2
#define REP1(i,x,y) for(int i=x;i
#define REP2(i,x,y) for(int i=x;i<=y;i++)
#define ls (2*k)
#define lr (2*k+1)
#define lson l,mid,2*k
#define lron mid+1,r,2*k+1
#define inf 0x3f3f3f3f3f3f3f3f
#define IOS ios::sync_with_stdio(0);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int dx[4] = { 0,-1,0,1 }, dy[4] = { 1,0,-1,0 };
int u[50005],v[50005],w[50005],d[50005];
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>u[i]>>v[i]>>w[i];
w[i]=-w[i];
}
for(int i=1;i<=n;i++)
d[i]=INT_MAXs;
d[1]=0;
for(int i=0;i<n-1;i++)
{
int flag=0;
for(int i=1;i<=m;i++)
{
if(d[v[i]]>d[u[i]]+w[i])
{
d[v[i]]=d[u[i]]+w[i];
flag=1;
}
}
if(!flag)
break;
}
if(d[n]==INT_MAXs)
printf("-1");
else
printf("%d",-d[n]);
return 0;
}
P2853 [USACO06DEC]Cow Picnic S
有多少个点可以让所有奶牛到达
每个牛的点都跑一边dfs,计算出有k头牛的位置
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define INT_MINs -2000000000
#define INT_MAXs 1000000001
#define mod 1000000007
#define MID mid=(l+r)/2
#define REP1(i,x,y) for(int i=x;i
#define REP2(i,x,y) for(int i=x;i<=y;i++)
#define ls (2*k)
#define lr (2*k+1)
#define lson l,mid,2*k
#define lron mid+1,r,2*k+1
#define inf 0x3f3f3f3f3f3f3f3f
#define IOS ios::sync_with_stdio(0);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int dx[4] = { 0,-1,0,1 }, dy[4] = { 1,0,-1,0 };
int num[1005],n,m,k,a[1005],vis[1005];
vector<int>vt[1005];
void dfs(int x)
{
num[x]++;
vis[x]=1;
for(int i=0;i<vt[x].size();i++)
{
int v=vt[x][i];
if(!vis[v])
{
dfs(v);
}
}
}
int main()
{
cin>>k>>n>>m;
for(int i=0;i<k;i++)
{
cin>>a[i];
}
for(int i=0;i<m;i++)
{
int u,v;
cin>>u>>v;
vt[u].push_back(v);
}
for(int i=0;i<k;i++)
{
memset(vis,0,sizeof(vis));
dfs(a[i]);
}
int ans=0;
for(int i=1;i<=n;i++)
if(num[i]==k)
ans++;
printf("%d",ans);
return 0;
}
P1983 车站分级
计算车站有多少个级别
计算车站最高等级的是多少级,就是有多少个级别,每一趟铁轨,没有停靠的车站都比停靠的级别要小,对每个点未停靠的点看成先于停靠的,就变成裸的拓扑
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define INT_MINs -2000000000
#define INT_MAXs 1000000001
#define mod 1000000007
#define MID mid=(l+r)/2
#define REP1(i,x,y) for(int i=x;i
#define REP2(i,x,y) for(int i=x;i<=y;i++)
#define ls (2*k)
#define lr (2*k+1)
#define lson l,mid,2*k
#define lron mid+1,r,2*k+1
#define inf 0x3f3f3f3f3f3f3f3f
#define IOS ios::sync_with_stdio(0);
#define pb(a) push_back(a)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int dx[4] = { 0,-1,0,1 }, dy[4] = { 1,0,-1,0 };
vector<int>vt[1005];
int deep[1005],is[1005],n,m,a[1005],num[1005];
bool vis[1005][1005];
void tp()
{
queue<int>q;
for(int i=1;i<=n;i++)
{
if(!num[i])
{
q.push(i);
deep[i]=1;
}
}
int ans=1;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=0;i<vt[u].size();i++)
{
int v=vt[u][i];
num[v]--;
if(!num[v])
{
q.push(v);
deep[v]=deep[u]+1;
ans=max(ans,deep[v]);
}
}
}
printf("%d",ans);
}
int main()
{
cin>>n>>m;
for(int i=0;i<m;i++)
{
memset(is,0,sizeof(is));
memset(a,0,sizeof(a));
int k;
cin>>k;
for(int j=1;j<=k;j++)
{
cin>>a[j];
is[a[j]]=1;
}
for(int j=a[1]+1;j<=a[k];j++)
{
if(!is[j])
for(int p=1;p<=k;p++)
{
if(!vis[j][a[p]])
{
num[a[p]]++;
vis[j][a[p]]=true;
vt[j].pb(a[p]);
}
}
}
}
tp();
return 0;
}