Description
给出一张有向图,先可以给其加任意条边使得其满足以下条件:
1.从
i
点出发可以到达
2.对任一条边 u→v 有 u<v
3.两点之间至多一条边
4.
i
到
5.
i
到
问加边的方案数
Input
第一行三个整数
n,m,k
,之后
m
行每行输入两个整数
Output
输出方案数,结果模 109+7
Sample Input
7 8 2
1 2
2 3
3 4
3 6
4 5
4 7
5 6
6 7
Sample Output
2
Solution
为满足五个要求,首先
i→i+1
的边都要有,其它边的长度必须为
k
,且长度为
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=1000005;
#define mod 1000000007
int Pow(int a,int b)
{
if(b<0)return 0;
int ans=1;
while(b)
{
if(b&1)ans=(ll)ans*a%mod;
a=(ll)a*a%mod;
b>>=1;
}
return ans;
}
int main()
{
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
int flag=1,L=n+1,R=0,num=0;
while(m--)
{
int u,v;
scanf("%d%d",&u,&v);
if(v!=u+1&&v!=u+k+1)flag=0;
else if(v==u+k+1)
{
L=min(L,u);
R=max(R,u);
num++;
}
}
if(R&&R-L>k)flag=0;
int ans;
if(!flag)ans=0;
else
{
if(R)
{
ans=0;
for(int i=max(R-k,1);i<=L;i++)
{
int res=min(i+k,n-k-1)-i-num;
if(i==L)res++;
ans=(ans+Pow(2,res))%mod;
}
}
else
{
ans=1;
for(int i=1;i<=n-(k+1);i++)ans=(ans+Pow(2,min(n-k-1,i+k)-i))%mod;
}
}
printf("%d\n",ans);
return 0;
}