Police Cities


Time Limit: 10 Seconds      Memory Limit: 32768 KB

Once upon the time there lived a king and he had a big kingdom. And there were n cities in his kingdom and some of them were connected by the roads. And the roads were all one-way because it would be dangerous if two carriages riding in opposite directions met on a road.

And once the king decided that he would like to establish police in his country and ordered to build police stations in some cities. But since his finances are limited, he would only like build police stations in k different cities. He would like to build them in such a way, that the following conditions were satisfied:

  • it is possible to get by the roads from each city to some city with the police station;
  • it is possible to get by the roads to each city from some city with the police station.

Now the king wants to know how many different ways are there to do so. Help him to find the answer to this question.

Input

There are mutilple cases in the input file.

The first line of each case contains n , m and k --- the number of cities and roads in the kingdom, and the number of police stations to build, respectively (1 <= n <= 100 , 0 <= m <= 20,000 , 1 <= k <= n ). The following m lines contain two city numbers each and describe roads, remember that it is only possible to travel along roads in one direction --- from the first city to the second one. Two cities may be connected by more than one road.

There is an empty line after each case.

Output

Output the only integer number --- the number of ways to fulfil king's request.

There should be an empty line after each case.

Sample Input

6 7 3
1 2
2 3
3 1
3 4
4 5
5 6
6 5

Sample Output

15

Source: Andrew Stankevich's Contest #9

解题:强连通分量缩点后进行dp

首先是入度为0或者出度为0的点必须安排那个警察,dp[i][j]表示前i个入度或者出度为0的强连通分量安排了j个警察

那么有转移方程 $dp[i][j] = \sum_{k = 0}^{k < j} dp[i-1][k]*c[x][j-k]$ 这些分量是必须至少要安置一个警司的,x表示该分量内点的数量

至于其余的,至少安放0个

 #include<bits/stdc++.h>

 using namespace std;

 #define MAXN 100
struct HP {
int len,s[MAXN];
HP() {
memset(s,,sizeof(s));
len=;
}
HP operator =(const char *num) { //字符串赋值
len=strlen(num);
for(int i=; i<len; i++) s[i]=num[len-i-]-'';
} HP operator =(int num) { //int 赋值
char s[MAXN];
sprintf(s,"%d",num);
*this=s;
return *this;
} HP(int num) {
*this=num;
} HP(const char*num) {
*this=num;
} string str()const { //转化成string
string res="";
for(int i=; i<len; i++) res=(char)(s[i]+'')+res;
if(res=="") res="";
return res;
} HP operator +(const HP& b) const {
HP c;
c.len=;
for(int i=,g=; g||i<max(len,b.len); i++) {
int x=g;
if(i<len) x+=s[i];
if(i<b.len) x+=b.s[i];
c.s[c.len++]=x%;
g=x/;
}
return c;
}
void clean() {
while(len > && !s[len-]) len--;
} HP operator *(const HP& b) {
HP c;
c.len=len+b.len;
for(int i=; i<len; i++)
for(int j=; j<b.len; j++)
c.s[i+j]+=s[i]*b.s[j];
for(int i=; i<c.len-; i++) {
c.s[i+]+=c.s[i]/;
c.s[i]%=;
}
c.clean();
return c;
} HP operator - (const HP& b) {
HP c;
c.len = ;
for(int i=,g=; i<len; i++) {
int x=s[i]-g;
if(i<b.len) x-=b.s[i];
if(x>=) g=;
else {
g=;
x+=;
}
c.s[c.len++]=x;
}
c.clean();
return c;
}
HP operator / (const HP &b) {
HP c, f = ;
for(int i = len-; i >= ; i--) {
f = f*;
f.s[] = s[i];
while(f>=b) {
f =f-b;
c.s[i]++;
}
}
c.len = len;
c.clean();
return c;
}
HP operator % (const HP &b) {
HP r = *this / b;
r = *this - r*b;
return r;
} HP operator /= (const HP &b) {
*this = *this / b;
return *this;
} HP operator %= (const HP &b) {
*this = *this % b;
return *this;
} bool operator < (const HP& b) const {
if(len != b.len) return len < b.len;
for(int i = len-; i >= ; i--)
if(s[i] != b.s[i]) return s[i] < b.s[i];
return false;
} bool operator > (const HP& b) const {
return b < *this;
} bool operator <= (const HP& b) {
return !(b < *this);
} bool operator == (const HP& b) {
return !(b < *this) && !(*this < b);
}
bool operator != (const HP &b) {
return !(*this == b);
}
HP operator += (const HP& b) {
*this = *this + b;
return *this;
}
bool operator >= (const HP &b) {
return *this > b || *this == b;
} }; istream& operator >>(istream &in, HP& x) {
string s;
in >> s;
x = s.c_str();
return in;
} ostream& operator <<(ostream &out, const HP& x) {
out << x.str();
return out;
}
const int maxn = ;
HP dp[maxn][maxn],c[maxn][maxn];
void calc() {
for(int i = ; i < maxn; ++i) {
c[i][] = c[i][i] = ;
for(int j = ; j < i; ++j)
c[i][j] = c[i-][j-] + c[i-][j];
}
}
int low[maxn],dfn[maxn],belong[maxn],bcc_size[maxn],bcc,clk;
vector<int>g[maxn],x,y;
stack<int>stk;
int n,m,K,ind[maxn],outd[maxn];
bool instack[maxn];
void init() {
for(int i = ; i < maxn; ++i) {
dfn[i] = belong[i] = bcc_size[i] = ;
g[i].clear();
instack[i] = false;
ind[i] = outd[i] = ;
}
bcc = clk = ;
while(!stk.empty()) stk.pop();
x.clear();
y.clear();
}
void tarjan(int u) {
dfn[u] = low[u] = ++clk;
stk.push(u);
instack[u] = true;
for(int i = g[u].size() - ; i >= ; --i) {
if(!dfn[g[u][i]]) {
tarjan(g[u][i]);
low[u] = min(low[u],low[g[u][i]]);
} else if(instack[g[u][i]]) low[u] = min(low[u],dfn[g[u][i]]);
}
if(low[u] == dfn[u]) {
bcc++;
int v;
do {
v = stk.top();
stk.pop();
belong[v] = bcc;
bcc_size[bcc]++;
instack[v] = false;
} while(v != u);
}
}
int main() {
calc();
int u,v;
while(~scanf("%d%d%d",&n,&m,&K)) {
init();
memset(dp,,sizeof dp);
for(int i = ; i < m; ++i) {
scanf("%d%d",&u,&v);
g[u].push_back(v);
}
dp[][] = ;
for(int i = ; i <= n; ++i)
if(!dfn[i]) tarjan(i);
for(int i = ; i <= n; ++i) {
for(int j = g[i].size()-; j >= ; --j) {
if(belong[i] == belong[g[i][j]]) continue;
ind[belong[g[i][j]]]++;
outd[belong[i]]++;
}
}
for(int i = ; i <= bcc; ++i)
if(!ind[i] || !outd[i]) x.push_back(i);
else y.push_back(i);
for(int i = ; i <= x.size(); ++i)
for(int j = ; j <= K; ++j)
for(int k = j-; k >= && j - k <= bcc_size[x[i-]]; --k)
dp[i][j] += dp[i-][k]*c[bcc_size[x[i-]]][j - k];
for(int i = x.size()+,t = ; i <= bcc; ++i,++t)
for(int j = x.size(); j <= K; ++j)
for(int k = x.size(); k <= j; ++k)
dp[i][j] += dp[i-][k]*c[bcc_size[y[t]]][j - k];
cout<<dp[bcc][K]<<endl<<endl;
}
return ;
}

ZOJ 2699 Police Cities的更多相关文章

  1. 100211D Police Cities

    传送门 分析 看到这个题我们的第一反应自然是Tarjan缩点,在这之后我们可以发现实际只要在缩点之后所有出度或入度为0的点布置警察局就可以达到要求,我们用dpij表示考虑前i个出度或入度为0的点共布置 ...

  2. 【ZOJ 3200】Police and Thief

    ZOJ 3200 首先我写了个高斯消元,但是消出来了一些奇怪的东西,我就放弃了... 然后只好考虑dp:\(dp[i][j][k]\)表示走到了第i步,到了\((j,k)\)这个节点的概率. 那么答案 ...

  3. 【转载】图论 500题——主要为hdu/poj/zoj

    转自——http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并 ...

  4. Codeforces Round #130 (Div. 2) C - Police Station 最短路+dp

    题目链接: http://codeforces.com/problemset/problem/208/C C. Police Station time limit per test:2 seconds ...

  5. ZOJ 3794 Greedy Driver

    两次SPFA 第一关找:从1没有出发点到另一个点的多少是留给油箱 把边反过来再找一遍:重每一个点到终点最少须要多少油 Greedy Driver Time Limit: 2 Seconds       ...

  6. ZOJ 1203 Swordfish 旗鱼 最小生成树,Kruskal算法

    主题链接:problemId=203" target="_blank">ZOJ 1203 Swordfish 旗鱼 Swordfish Time Limit: 2 ...

  7. POJ 2296 Map Labeler / ZOJ 2493 Map Labeler / HIT 2369 Map Labeler / UVAlive 2973 Map Labeler(2-sat 二分)

    POJ 2296 Map Labeler / ZOJ 2493 Map Labeler / HIT 2369 Map Labeler / UVAlive 2973 Map Labeler(2-sat ...

  8. ZOJ 3946.Highway Project(The 13th Zhejiang Provincial Collegiate Programming Contest.K) SPFA

    ZOJ Problem Set - 3946 Highway Project Time Limit: 2 Seconds      Memory Limit: 65536 KB Edward, the ...

  9. zoj 3747 递推dp

    Attack on Titans Time Limit: 2 Seconds      Memory Limit: 65536 KB Over centuries ago, mankind faced ...

随机推荐

  1. mysql 日期计算,今天,明天,本周,下周,本月,下月

    --今天 DATE_FORMAT(BIRTH_DATE,'%Y-%m-%d') = CURDATE() --明天 DATE_FORMAT(BIRTH_DATE,'%Y-%m-%d') = TIMEST ...

  2. RMAN 备份与恢复 实例

    1. 检查数据库模式:    sqlplus /nolog     conn /as sysdba    archive log list (查看数据库是否处于归档模式中) 若为非归档,则修改数据库归 ...

  3. svn for vs

    现在官方下载需要注册一堆的东西,为方便群众使用在这里提供一个新版的下载. http://files.cnblogs.com/wfcfan/AnkhSvn-2.5.12266.rar

  4. 洛谷 P3959 NOIP2017 宝藏 —— 状压搜索

    题目:https://www.luogu.org/problemnew/show/P3959 搜索: 不是记忆化,而是剪枝: 邻接矩阵存边即可,因为显然没有那么多边. 代码如下: #include&l ...

  5. Anaconda/kickstart

    http://fedoraproject.org/wiki/Anaconda/Kickstart/zh-cn

  6. git常见冲突及解决办法

    1.内容冲突 产生冲突的原因:两个用户修改了同一个文件的同一块区域,git会报告内容冲突.我们常见的都是这种. 解决冲突的办法:编辑冲突文件,修改冲突. 例如:冲突文件test.c test.c发生冲 ...

  7. Android插件化原理解析——Hook机制之动态代理

    转自 http://weishu.me/2016/01/28/understand-plugin-framework-proxy-hook/ 使用代理机制进行API Hook进而达到方法增强是框架的常 ...

  8. bootstrap-paginator基于bootstrap的分页插件

    bootstrap-paginator基于bootstrap的分页插件 GitHub 官网地址:https://github.com/lyonlai/bootstrap-paginator 步骤 引包 ...

  9. Java导入excel并保存到数据库

    首先建立好excel表格,并对应excel表格创建数据库表. 前台jsp页面:其中包含js <%@ page language="java" import="jav ...

  10. 扩展银行项目,添加一个(客户类)Customer类。Customer类将包含一个Account对象。

    练习目标-使用引用类型的成员变量:在本练习中,将扩展银行项目,添加一个(客户类)Customer类.Customer类将包含一个Account对象. 任务 在banking包下的创建Customer类 ...